1 IOCP 만들기

HANDLE CreateIoCompletionPort (
 HANDLE FileHandle,
 HANDLE ExistingCompletionPort,
 ULONG_PTR CompletionKey,
 DWORD NumberOfConcurrentThreads
);

이름 그대로 IOCP를 만들어 주는 함수 이다. 처음 IOCP를 만들 때는 네개의 인자 모두를 사용하는 것이 아니라 처음의 한개 인자만을 사용한다.그냥 단순히 IOCP를 생성하기만 하는 것 이므로,

HANDLE hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);

와 같이 생성하면 된다.

이제 IOCP를 생성했으므로, 앞에서 말했던 것 처럼 이 IOCP를 통해 입출력 완료가 일어난 결과를 통보 받기만 하면 된다.

결과를 통보 받는다 하여 사용자에게 이벤트나 기타의 방법으로 알려 주는 것이 아니다. IOCP는 입출력 완료가 일어나면 그 결과를 특정한 큐에 집어 넣어 둔다. 때문에 사용자는 이 큐를 항상 감시 하고 있어야 한다. 이 큐에 먼가가 들어 오게 되면 입출력 작업중 하나가 완료 된 것이다. 그럼, 이 큐를 감시할 스레드를 만들어야 할 것이다. 보통은 이 스레드를 작업자 스레드(WorkerThread)
라 부른다.

_beginthreadex(NULL, 0, WorkerThread, , (LPVOID)hIOCP, 0, NULL);

작업자 스레드까지 생성 했으므로, 실제로 입출력을 할 FileHandle을 만들어야 한다. 우리는 소켓을 통해 입출력을 할 것 이므로 소켓을 생성해 주면 된다. 물론 파일 핸들을 통해서도 네트웍입출력이 가능하긴하 지만 그냥 편하게 소켓을 사용하자.

소켓을 생성할 때 주의할 것은 이 소켓이 Overlapped가 가능한 소켓이어야 한다는 것 이다. 그냥 일반적으로 소켓을 생성하면 Overlapped가 가능한 소켓이 된다. Winsock2의 WSASocket()을 사용하여 처음 소켓을 만들때 Overlapped 인자를 주어 소켓을 생성할 수도 있다.

SOCKET hSocket = WSASocket(AF_INET, SOCKET_STREAM, 0, NULL, WSA_FLAG_OVERLAPPED);

이제 이 소켓을 IOCP에 연결 해 준다. 그럼 이 소켓에서 입출력 완료가 일어났을 때 완료 통보가 완료큐에 들어가게 되고, 그럼 이 완료큐를 감시하고 있던 스레드에서 그 결과를 가져와서 해당 작업을 할 수있게 되는 것 이다.

CreateIoCompletionPort((HANDLE)hSocket, hIOCP, CompletionKey, 0);

IOCP를 만들고, 스레드를 만들었고 소켓을 만들어 IOCP에 등록까지 마쳤다. 이제 소켓을 통해 입출력 작업을 하면 된다. 그러면 입출력 작업이 완료 되었을 때 우리는 그 결과를 가져 올 수 있을 것 이다.


그럼, 입출력이 완료 되었을 때 완료 큐에서 결과를 가져 오는 방법을 알아야 할 것 이다.
GetQueuedCompletionStatus(
 HANDLE CompletionPort,
 LPDWORD lpNumberOfBytes,
PULONG_PTR lpCompletionKey,
 LPOVERLAPPED *lpOverlapped,
 WORD dwMilliseconds
);

완료 큐에서 결과를 가져오는 함수 이다. 대충 인자를 살펴보아도 무슨 역할을 하는 지 알 수 있을 것 이다.

자 이제 이것으로 준비는 모두 끝 났다. 이것을 바탕으로 가장 기본적인 IOCP Echo Server를 만들어 보도록 하자.

'공부 해 Boa요. > Network' 카테고리의 다른 글

Raw Socket  (0) 2006.09.29
Consol Echo Client  (0) 2006.09.27
실전 네트웍 프로그래밍 - 4 - IOCP Echo Server  (0) 2005.06.29
'실전 네트웍 프로그래밍 - 2  (0) 2005.06.29
실전 네트웍 프로그래밍 - 1  (0) 2005.06.29

+ Recent posts