IOCP 기반 다중 접속 및 데이터 처리-3

반응형

이번 포스팅에서는 IOCP 서버에서 소켓 풀을 관리하는 방법에 대해 알아보겠습니다.

이전 포스팅에서 IOCP 뼈대 코드를 작성하고 초기화하는 과정을 알아보았습니다.

2023.12.13 - [프로그래밍/C | C++] - IOCP 기반 다중 접속 및 데이터 처리-1

 

IOCP 기반 다중 접속 및 데이터 처리-1

윈도 환경에서 다중 클라이언트의 접속을 처리하는 네트워크 서버를 구현하기 위해서는 IOCP 사용이 필수라고 생각합니다. 에코 서버를 IOCP 기반으로 구현한 예제는 많지만 실제 현업에서 다중

blog.noyecube.com

2023.12.14 - [프로그래밍/C | C++] - IOCP 기반 다중 접속 및 데이터 처리-2

 

1. 리슨소켓 Accept 이벤트 감지

Accept 이벤트 감지 처리

  • WSAEVENT hWSAEvent = WSACreateEvent()
    상태 변경에 대한 통지를 받을 이벤트 커널 객체 생성(초기: 넌시그널) 코드입니다.
  • WSAEventSelect(hsoListen, hWSAEvent, FD_ACCEPT)
    리슨소켓에 ACCEPT 이벤트가 발생하면 hWSAEvent가 Set 상태가 되도록 설정합니다.
  • WSAEnumNetworkEvents(hsoListen, hWSAEvent, &ne)
    소켓 변경사항 체크 및 네트워크 이벤트 레코드 클리어, 이벤트 커널 객체 리셋을 수행합니다.

2. 소켓 풀 생성/재사용 및 비동기 접속 처리

IncreaseAcceptSockets

리슨소켓(hsoListen)으로부터 들어오는 접속을 수용할 신규 소켓(sock)을 미리 생성하고 OVERLAPPED 구조체 포인터 변수와 함께 AcceptEx()를 호출하여 비동기 접속을 수용합니다. 한 번에 nIncCnt 값만큼 소켓을 미리 생성해 둡니다.

AcceptEx 함수 호출 시 OVERLAPPED 구조체를 이용하면 접속이 들어왔을 때 리슨 소켓의 핸들 자체가 시그널 상태가 됩니다. 이때 미리 생성해 둔 소켓이 없으면 WSAEventSelect 함수로 전달된 이벤트가 시그널 상태가 되어 미리 생성해둔 소켓이 모두 소진되었음을 알립니다.

GetListenSocket

비동기 리슨 소켓을 생성 후 리슨 소켓 핸들로 IOCP 핸들을 생성합니다. 

GetQueuedCompletionStatus

hsoListen이 IOKEY_LISTION 키값으로 IOCP 등록되어 있으므로 GetQueuedCompletionStatus에서 신규 접속 클라이언트 이벤트를 감지할 수 있습니다. 신규 접속이 감지되면 CreateIoCompletionPort 호출로 접속한 클라이언트의 소켓에 대해 데이터 수신 이벤트도 감지 등록합니다.

소켓 재사용 코드

클라이언트가 접속을 종료하면 Socket Close를 호출하는 대신 DisconnectEx를 호출합니다. 그럼 소켓이 버려지는 것이 아니고 연결만 닫히게 됩니다. 이를 통해 소켓을 생성/소멸하는데 필요한 오버헤드를 줄일 수 있습니다. Disconnect가 완료되면 다시 AcceptEx를 호출하여 소켓을 재사용합니다. 유의 사항으로는 소켓이 재사용되므로 상위 레벨에서 클라이언트의 변경을 알아차릴 수 있는 자료구조를 제공해야 합니다. 

반응형