GameChoi 2023. 1. 14. 21:48

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

https://choiprogramming.tistory.com/113

 

[SERVER] Overlapped I/O

1. Overlapped I/O 1.1 Overlapped I/O 의미 - 하나의 스레드에서 둘 이상의 패킷 데이터를 통신용 소켓에 송수신 - 여러 개의 소켓에 입출력이 중첩된 상황 1.2 Non-blocking Code 수정 https://choiprogramming.tistory.com

choiprogramming.tistory.com