1. IOCP
1.1 Overlapped I/O와 IOCP의 차이점
- Thread Pooling
- 재사용이 가능한 스레드를 유지할 수 있는 최적화 된 기능
1.2 IOCP
- TCP로 서로 송수신할 때 WSASend / WSARecv와 같은 비동기 입출력 함수를 호출
- 스레드에서 내부적으로 APC(Asynchronous Procedure Call Queue) 큐가 생성
- 입출력이 완료된 결과를 저장
- 사용자가 생성한 IOCP 커널 객체에 접근하는 여러 스레드들을 두고 입출력 결과를 처리
- IOCP 객체 생성
- FileHandle: IOCP와 연결할 HANDLE 지정
- IOCP 객체를 생성해야하므로 INVALD_HANDLE_VALUE을 사용
- ExistingCompletionPort: 이미 만들어진 IOCP 핸들을 입출력 완료 포트에 지정
- CompletionKey: IOCP 핸들을 KEY로 유저가 정의한 값
- NumberOfConcurrentTreads: 한 번에 동작할 수 있는 최대 스레드 개수 지정
HANDLE WINAPI CreateIoCompletionPort(
HANDLE FileHandle,
HANDLE ExistingCompletionPort,
ULONG_PTR CompletionKey,
DWORD NumberOfConcurrentThreads
);
int main()
{
// Init WSA, Socket Create, Server IP/HOST
// Non-Blocking Socket, BIND, LISTEN
// IOCP HANDLE Create
HANDLE iocpHandle = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
// Close WSA
}
- 쓰레드 풀을 생성해 IOCP 큐에 변화가 있는 지 확인
- GetQueuedCompletionStatus 사용 (TODO)
int main()
{
// Init WSA, Socket Create, Server IP/HOST
// Non-Blocking Socket, BIND, LISTEN
// IOCP HANDLE Create
// Thread Pool Create
vector<thread> td;
for (int i = 0; i < 3; i++)
td.push_back(thread([=]() {Worker(iocpHandle); }));
// Close WSA
}
- Accept Socket & IOCP Handle
- 힙 메모리에 생성한 구조체의 주소를 키 값으로 IOCP 커널 객체에 연결되어 있는 연결 장치의 식별 가능
int main()
{
// Init WSA, Socket Create, Server IP/HOST
// Non-Blocking Socket, BIND, LISTEN
// IOCP HANDLE Create, Thread Pool Create
while (true)
{
// accept
// 생성한 accept Socket과 IOCP HANDLE을 묶음
::CreateIoCompletionPort((HANDLE)clientSocket, iocpHandle, (ULONG_PTR)session, 0);
// Close WSA
}
- 클라이언트로 부터 받는 것을 대기 및 큐에 전달
int main()
{
// Init WSA, Socket Create, Server IP/HOST
// Non-Blocking Socket, BIND, LISTEN
// IOCP HANDLE Create, Thread Pool Create
while (true)
{
// accept
// 생성한 accept Socket과 IOCP HANDLE을 묶음
// 필요한 변수 생성 후 비동기 상태로 메시지 대기
::WSARecv(clientSocket, &wsaBuf, 1, &recvLength, &flags, &overlappedEx->overlapped, NULL);
// Close WSA
}
1.3 IOCP Worker
- GetQueueCompletionStatus
- Blocking Function
- 쓰레드를 통해 해당 Completion Port에서 큐에 완료보고가 들어오는 지 검사
- IOCP의 핸들 값을 바탕으로 위에서 보낸 session 값과 overlapped 값을 받음
bool ret = ::GetQueuedCompletionStatus(iocpHandle, &bytesTransferred,
(ULONG_PTR*)&session, (LPOVERLAPPED*)&overlapped, INFINITE);
- 큐에서 완료보고가 오면 원하는 일 처리
2, Client
'Create Game > [Window API] Game Client & Game Server' 카테고리의 다른 글
[GameServer] 2. Server Service (0) | 2023.01.18 |
---|---|
[GameServer] 1. IOCP Server Core & Accept (0) | 2023.01.17 |
[SERVER] Overlapped I/O (0) | 2023.01.14 |
[SERVER] WSAEvent Select (0) | 2023.01.13 |
[SERVER] Select (1) | 2023.01.12 |