● 관련 함수
HANDLE WINAPI CreateIoCompletionPort(
_In_ HANDLE FileHandle,
_In_opt_ HANDLE ExistingCompletionPort,
_In_ ULONG_PTR CompletionKey,
_In_ DWORD NumberOfConcurrentThreads
);
BOOL GetQueuedCompletionStatus(
HANDLE CompletionPort,
LPDWORD lpNumberOfBytesTransferred,
PULONG_PTR lpCompletionKey,
LPOVERLAPPED *lpOverlapped,
DWORD dwMilliseconds
);
BOOL WINAPI PostQueuedCompletionStatus(
_In_ HANDLE CompletionPort,
_In_ DWORD dwNumberOfBytesTransferred,
_In_ ULONG_PTR dwCompletionKey,
_In_opt_ LPOVERLAPPED lpOverlapped
);
● WSARecv와 recv함수를 같이 사용하는 이유 (Zero byte buffer)
윈도우에서 관리하는 일부 메모리들은 하드 디스크로 페이징되서는 안되는 블럭들이 있는데 Non-paged 메모리라고 한다.
그런데 WSARecv 함수에서 일정 사이즈의 버퍼를 제공한다면 그 메모리들이 Non-paged 메모리로 인식이 된다.
Pandding된 WSARecv 수가 많고, 버퍼 사이즈들이 크다면, 제한된 메모리를 전부 차지하는 현상이 발생한다.
그래서 WSARecv에 0바이트로 받아 IOCP에 수신 신호만 들어오게 하고 실제 데이터를 recv함수로 받는다.
(이 경우 Iocp queue의 수신 byte가 0이고, 이 경우 접속 종료를 처리해선 안된다)
● 클라이언트와 연결이 끊어짐을 확인하는 방법
1. Recv bytes가 0인 경우
- zero byte buffer를 사용한 경우를 제외하고
2. GetQueuedCompletionStatus 함수 호출 결과가 false일때
3. 별도의 CS간 heartbeat를 설정한다
- SO_KEEPALIVE: 모든 소켓에 적용 (2시간 단위)
- SIO_KEEPALIVE_VALS: 특정 소켓에만 적용 (윈 2000 이상,
- 그 외 직접 Heart beat 제작
● 서버-클라이언트간 연결을 종료할 때
1. send되지 않고 버퍼에 남아있는 data 처리.
- TCP의 LINGER 옵션 사용
2. Recv, Send 완료 통보가 모두 도착했는지 확인 (전송량도 확인)
3. 되도록 서버에서보다는 클라이언트에서 closesocket 함수를 호출하긴 권장
'서버 > IOCP' 카테고리의 다른 글
IOCP 관련 advance (0) | 2021.09.09 |
---|---|
page-locking (0) | 2021.09.09 |