본문 바로가기

공부/tcp/ip 프로그래밍

21장 Asynchronous Notification IO 모델

반응형

 21장.pptx

동기와 비동기에 대한 이해

위 : 동기

아래 : 비동기

 

*동기화된 입출력의 단점과 비동기의 해결책
동기화된 입출력의 단점
입출력이 진행되는 동안 호출된 함수가 반환을 하지 않으니, 다른 일을 할 수가 없다

 

비동기의 해결책
데이터의 송수신 완료에 상관없이, 호출된 함수가 반환을 하기 때문에 다른 일을 진행 할
수 있음

 

*Notification(알림) IO(입출력)
입력버퍼에 데이터가 수신되어서 데이터의 수신이 필요하거나, 출력버퍼가 비어서
데이터의 전송이 가능한 상황의 알림

 

*동기화된 Notification IO모델
가장 대표적인 동기화된 Notification IO모델은 select방식
IO가 필요한 또는 가능한 상황이 되는 시점이(간단히 말해서 IO관련 이벤트의 발생
시점이) select함수가 반환하는 시점과 일치한다

 

*비동기 Notification IO모델
WSAEventSelect함수가 해당됨
IO의 관찰을 명령하기 위한 함수호출과 실제로 상태의 변화를 확인하는 함수호출

 

*비동기 Notification IO모델의 구현방법
1. WSAEventSelect 함수
2. WSAAsyncSelect 함수

 

 비동기 Notification IO모델의 구현 순서

1. WSACreateEvent() : manual-reset모드 Event 오브젝트 생성, 배열에 내용저장

 

2. WSAEventSelect() :

    소켓과 Event 오브젝트를 연결하여 소켓의 이벤트 발생시 Event 오브젝트가 signaled상태로 바뀜, os에 등록

 

3. WSAWaitForMultipleEvents() : WSAEVENT배열에서 signaled 상태로 전이된 Event 오브젝트를 찾음

 

4. WSAEnumNetworkEvents() : 소켓과 소켓에 연결된 Event 오브젝트의 핸들을 통해 발생한 이벤트의 유형정보, 오류정보를 알아냄

 

manual-reset모드 Event 오브젝트의 생성함수

#include <winsock2.>

 

WSAEVENT WSACreateEvent(void);

성공 시 Event 오브젝트 핸들, 실패 시 WSA_INVALID_EVENT 반환

 

#define WSAEVENT HANDLE 라고 정의되어 있음

 

manual-reset모드 Event 오브젝트의 삭제함수

#include <winsock2.h>

 

BOOL WSACloseEvent(WSAEVENT hEvent);

성공 시 TRUE, 실패 시 FALSE반환

 

임의의 소켓을 대상으로 이벤트 발생여부의 관찰을 명령하는 함수

매개변수 s에 전달된 핸들의 소켓에서 lNetworkEvents에 전달된 이벤트 중 하나가 발생하면, hEventObject에 전달된 핸들의 커널 오브젝트를 signaled 상태로 바꾸는 함수

#include <winsock2.h>

 

int WSAEventSelect(SOCKET s, WSAEVENT hEvvnetObject, long lNetworkEvents);

성공시 0, 실패시 SOCKET_ERROR 반환

 

s : 관찰대상인 소켓의 핸들 전달

hEventObject : 이벤트 발생유무의 확인을 위한 Event 오브젝트의 핸들 전달

lNetworkEvents : 감시하고자 하는 이벤트의 유형 정보전달

 

3번째 인자로 전달될 수 있는 이벤트의 종류

1. FD_READ 수신할 데이터가 존재하는가?

2. FD_WRITE 블로킹 없이 데이터 전송이 가능한가?

3. FD_OOB out-of-band 데이터가 수신되었는가?

4. FD_ACCEPT 연결요청이 있었는가?

5. FD_CLOSE 연결의 종료가 요청되었는가?

 

이벤트 발생유무의 확인하는 함수(= WaitForMultipleObjects함수)

#include <winsock2.h>

 

DWORD WSAWaitForMultipleEvents(

DWORD cEvents, const WSAEVENT* lphEvents, BOOL fWaitAll, DWORD dwTimeout, BOOL fAlertable);

성공 시 이벤트 발생 오브젝트 관련정보, 실패 시 WSA_INVALID_EVENT 반환

 

cEvents : signaled 상태로의 전이여부를 확인할 Event 오브젝트의 개수 정보 전달

lphEvents : Event 오브젝트의 핸들을 저장하고 있는 배열의 주소 값 전달

fWaitAll : TRUE 전달 시 모든 Event 오브젝트가 signaled 상태일 때 반환, FALSE 전달 시 하나만 signaled 상태가 되어도 반환

dwTmeout : 1/1000초 단위로 타임아웃 지정, WSA_INFINITE 전달 시 signaled 상태가 될 때까지 반환하지 않는다

fAlertable : TRUE 전달 시, alertable wait 상태로의 진입

반환 값 : 반환된 정수 값에서 상수 값 WSA_WAIT_EVENT_0을 빼면, 두 번째 매개변수로 전달된 배열을

              기준으로, signaled상태가 된 Event 오브젝트의 핸들이 저장된 인덱스가 계산된다.

              만약에 둘 이상의 Event 오브젝트가 signaled상태로 전이 되었다면, 그 중 작은 인덱스 값이

              계산된다.

              그리고 타임아웃이 발생하면 WAIT_TIMEOUT이 반환된다.

 

해당 오브젝트가 signaled 상태가 된 원인을 확인하는 함수

#include <winsock2.h>

 

int WSAEnumNetworkEvents(

SOCKET s, WSAEVENT hEvnetObject, LPWSANETWORKEVENTS lpNetworkEvents);

성공 시 0, 실패 시 SOCKET_ERROR 반환

 

s : 이벤트가 발생한 소켓의 핸들 전달

hEventObject : 소켓과 연결된(WSAEventSelect 함수 호출에 의해), signaled 상태인 Event 오브젝트의

                     핸들 전달

lpNetworkEvents : 발생한 이벤트의 유형정보와 오류정보로 채워질 WSANETWORKEVENTS 구조체 변수의

                          주소 값 전달

 

typedef struct _WSANETWORKEVENTS

{

long lNetworkEvents;

int iErrorCode[FD_MAX_EVENTS];

} WSANETWORKEVENTS, *LPWSANETWORKEVENTS;

 

발생한 이벤트의 종류를 확인하는 방법

WSANETWORKEVENTS netEvents;

WSAEnumNetworkEvents(hSock, hEvent, &netEvents);

if(netEvents.lNetworkEvents & FD_ACCEPT)

{

// FD_ACCEPT 이벤트 발생에 대한 처리

}

 

오류발생에 대한 정보를 확인하는 방법

WSANETWORKEVENTS netEvents;

WSAEnumNetworkEvents(hSock, hEvent, &netEvents);

if(netEvents.iErrorCod[FD_READ_BIT] != 0)

{

// FD_READ 이벤트 관련 오류발생

}

반응형