WSAEventSelect 모델

Jaemyeong Lee·2025년 1월 25일

게임 서버1

목록 보기
134/220

등장 배경과 핵심 아이디어

왜 Select 다음에 배우는가

  • Select는 매 루프마다 fd_set 재구성과 순회가 필요합니다.
  • WSAEventSelect는 "소켓에 이벤트를 연결"해서 준비 상태를 더 직접적으로 기다립니다.
  • 즉, Reactor 모델을 Windows 이벤트 객체 기반으로 구현한 형태입니다.

Select와 비교

SelectWSAEventSelect
fd_set 구성 후 select()소켓-이벤트 연동 후 WSAWaitForMultipleEvents()
FD_ISSET으로 준비 확인WSAEnumNetworkEvents로 이벤트 종류 확인
집합 기반 폴링 성격이벤트 신호 기반 대기

핵심 요약

  • "준비됐는지 매번 확인"에서 "준비되면 깨워줌"으로 사고가 바뀝니다.

주요 API와 이벤트 종류

주요 API

함수역할
WSACreateEvent()이벤트 객체 생성
WSAEventSelect(sock, ev, mask)소켓과 이벤트 객체 연동
WSAWaitForMultipleEvents()이벤트 배열 대기
WSAEnumNetworkEvents()실제 발생 이벤트 확인 + 내부 상태 정리
WSACloseEvent()이벤트 객체 해제

자주 쓰는 이벤트 마스크

이벤트의미
FD_ACCEPT수락 가능한 연결 도착
FD_READ읽을 데이터 도착
FD_WRITE쓸 수 있는 상태
FD_CLOSE연결 종료 감지
FD_CONNECTconnect 완료/실패

기본 처리 흐름

초기화 패턴

WSAEVENT ev = WSACreateEvent();
WSAEventSelect(sock, ev, FD_READ | FD_CLOSE);

대기 루프 예시

DWORD idx = WSAWaitForMultipleEvents(eventCount, events,
                                     FALSE, 1000, FALSE);
if (idx == WSA_WAIT_TIMEOUT) {
    // 주기 작업
} else if (idx >= WSA_WAIT_EVENT_0 &&
           idx < WSA_WAIT_EVENT_0 + eventCount) {
    int i = static_cast<int>(idx - WSA_WAIT_EVENT_0);
    WSANETWORKEVENTS ne{};
    WSAEnumNetworkEvents(sockets[i], events[i], &ne);

    if (ne.lNetworkEvents & FD_READ)  { /* recv */ }
    if (ne.lNetworkEvents & FD_CLOSE) { /* close */ }
}

처리 순서 규칙

  1. 대기
  2. 어떤 이벤트가 깨어났는지 인덱스 확인
  3. WSAEnumNetworkEvents로 실제 이벤트 플래그 확인
  4. 해당 I/O 처리

중요한 동작 규칙(실수 포인트)

자동 논블로킹 전환

  • WSAEventSelect를 호출하면 해당 소켓은 논블로킹 모드로 동작합니다.
  • 따라서 recv/send에서 WSAEWOULDBLOCK 분기가 계속 필요합니다.

이벤트 리셋

  • WSAEnumNetworkEvents 호출 시 연결된 이벤트 객체 상태가 정리됩니다.
  • 이 호출을 누락하면 같은 이벤트가 반복되거나 상태가 꼬일 수 있습니다.

이벤트 해제

  • 소켓 종료 시 closesocket뿐 아니라 WSACloseEvent도 잊지 않아야 합니다.
  • 이벤트 핸들 누수는 장기 실행 서버에서 치명적입니다.

성능 한계와 적용 범위

꼭 알아야 할 한계

  • Windows 전용 모델입니다.
  • WSAWaitForMultipleEvents는 한 번에 기다릴 수 있는 이벤트 수가 제한됩니다.
  • 일반적으로 WSA_MAXIMUM_WAIT_EVENTS(64) 제약 때문에 대규모 서버에는 부적합합니다.

실제 적용 권장

시나리오권장
소켓 수가 적은 도구/클라이언트WSAEventSelect 충분
중간 규모 서버 프로토타입가능하지만 관리 복잡도 증가
대규모 동접 게임 서버IOCP 권장

결론

  • WSAEventSelect는 Select보다 이벤트 지향적이지만,
  • 규모가 커지면 결국 IOCP 같은 완료 기반 모델로 넘어가는 징검다리입니다.

강의 시 유의사항

강조 포인트

  • Select -> WSAEventSelect -> IOCP의 진화 흐름을 반드시 연결해 설명하세요.
  • "이벤트 모델"이지만 여전히 논블로킹 분기 처리(WOULDBLOCK)가 필요함을 강조하세요.
  • 64 제한(대기 핸들 수)을 실무 한계로 명확히 짚으세요.

자주 하는 오해

오해바로잡기
WSAEventSelect는 소켓 수 제한이 없다대기 이벤트 수 제한이 존재
이벤트가 오면 무조건 recv 성공FD_READ 후에도 분기/오류 처리가 필요
이벤트 객체는 소켓 닫으면 자동 정리WSACloseEvent로 별도 해제 필요

체크 질문 (스스로 답해보기)

  • WSAEnumNetworkEvents 호출이 필수인가?
  • WSAEventSelect가 소규모에는 충분하지만 대규모 서버에는 부적합한 이유는?
  • WSAEventSelect 설정 후 recv 코드가 기존과 어떻게 달라져야 하는가?

profile
李家네_공부방

0개의 댓글