먼저 IOCP 객체를 만듭니다(➊). 여러 소켓과 소켓에 대응하는 여러분이 원하는 정수 값(epoll의 userptr과 동일)을 IOCP에 추가합니다(➋). 추가된 소켓의 I/O 이벤트는 IOCP를 이용하여 감지할 수 있습니다. I/O를 하고 싶으면 Overlapped I/O를 겁니다(➏).
모든 Overlapped status 객체에 대한 GetOverlappedResult 대신 IOCP에서 완료 신호를 꺼내 오는 함수를 호출합시다. 이 함수는 사용자가 원하는 시간까지만 블로킹되며, 그 전에 이벤트가 생기면 즉시 리턴합니다(➌). 출력 값에는 꺼내 온 이벤트들이 있습니다.
각 이벤트에 대해 루프를 돌면서(➍), 이벤트가 가리키는 Overlapped status 객체와 대응하는 user ptr 값을 꺼내 온 후 원하는 처리를 하면 됩니다(➎). 추가로 I/O를 계속 하고 싶으면 Overlapped I/O를 또 걸면 됩니다(➏).
epoll과 꽤 비슷하지 않나요? 차이점이 있다면 epoll은 I/O 가능인 것을 알려 주지만, IOCP는 I/O 완료인 것을 알려 준다는 것입니다.
IOCP는 epoll보다 훨씬 오래 전에 나온 API입니다. 그러다 보니 epoll과 비교했을 때 사용법에 복잡한 기능이 몇 가지 있는데, 그중 하나가 바로 Accept 처리입니다.
1. IOCP에 listen socket L을 추가했다면, L에서 TCP 연결을 받을 경우 이에 대한 완료 신호가 IOCP에 추가됩니다.
2. 단 사전에 이미 AcceptEx로 Overlapped I/O를 건 상태여야 합니다.
3. IOCP로 L에 대한 이벤트를 얻어 왔지만, 앞서 Overlapped accept처럼 SO_UPDATE_ACCEPT_CONTEXT와 관련된 처리를 해 주어야 새 TCP 소켓 핸들을 얻어 올 수 있습니다.