우리가 데이터 송수신에 사용하는 함수 WSASend(), WSARecv()는 파라미터로 넘겨진 버퍼가 페이징 되지 않도록 페이지 단위(윈도우에서는 4KB)의 락을 걸게 된다.
운영체제는 이러한 페이지의 최대치가 존재하는데, 이 한계를 넘길 경우 Overlapped I/O는 실패하게 된다.
그래서 우리는 흔히 ZeroByte Recv이라는 꼼수를 통해 이벤트 발생과 데이터의 수신을 분리해서 락이 걸리는 페이지를 줄이는 방법을 사용한다.
WSABUF wsabuf;
wsabuf.buf = nullptr;
wsabuf.len = 0;
::WSARecv(socket, &wsabuf, 1, NULL, &dwFlag, (LPWSAOVERLAPPED)&over_recv, NULL);
WSARecv 함수를 이렇게 호출하면 GQCS에서는 0 크기의 데이터 수신(이벤트)가 감지되는데, 이 때 다시 실제 버퍼를 인자로 해서 다시 recv 요청을 진행한다.
switch(overlapped->iotype)
{
case IO_RECV:
if (user->IsZeroRecv())
{
::WSARecv(user->GetSocket(), user->GetWsaBuf(), 1, NULL, &dwFlag, (LPWSAOVERLAPPED)&user->GetOverLapped(), NULL);
continue;
}
ProcPacket(...);
}
https://snowfleur.tistory.com/193
[게임서버] IOCP Page-Locking
Page-Locking IOCP에서 WSASend 혹은 WSARecv를 할 때 기본적으로 Overlapped IO 방식으로 IO를 수행한다. WSASend 와 WSARecv는 버퍼를 직접 제공한다.(WSABUF) 이 때 이 버퍼는 IO 과정에서 커널이 직접 접근해..
snowfleur.tistory.com
https://chfhrqnfrhc.tistory.com/entry/pagelocking-nonpaged-pool
page-locking & non-paged pool
1. page-locking WSASend()나 WSARecv()의 경우 상황에 따라 제공된 버퍼가 페이징되지 않도록 lock을 걸게 된다. WSASend()의 경우는 소켓 버퍼가 가득찰 경우일 것이고, WSARecv()의 경우 소켓버퍼로 부터 받을.
chfhrqnfrhc.tistory.com
https://blog.naver.com/spaciall/222701974635
IOCP 프로그래밍, Page-Locking & Non-Paged Pool & ZeroByteRecv
IOCP 프로그래밍을 하게 되면 그 안에 들어있는 이론인 페이지 락킹과 논페이지 풀에 대해서 알아보도...
blog.naver.com
'서버 > IOCP' 카테고리의 다른 글
IOCP 관련 advance (0) | 2021.09.09 |
---|---|
IOCP 관련 정리 (0) | 2020.08.23 |