WSAEventSelect함수는 비동기 함수이다.
소켓과 관련된 네크워크 이벤트를 [이벤트 객체]를 통해 감지한다.
비동기 함수라서 WSAEventSelect()함수가 리턴값을 받지 않는다.
WSAWaitForMultipleEvents() 함수로 완료 인덱스를 받아와 이벤트를 추적해야한다.
Select 모델에 비해 매번 초기에 전체 리셋을 할 필요가 없는 장점이 있다.
WSA_MAXIMUM_WAIT_EVENTS(64)개의 최대 갯수 제한이 있다.
Select 모델과 마찬가지로 간단한 클라이언트에 적합한 입출력 모델이다.
// 이벤트 객체 관련 함수들
생성: WSACreateEvent (수동 리셋 Manual-Reset + Non-Signaled 상태 시작)
삭제: WASCloseEvent
신호 상태 감지: WSAWaitForMultipleEvents
구체적인 네트워크 이벤트 알아내기: WSAEnumNetworkEvents
소켓 <-> 이벤트 객체 연동
소켓 갯수 만큼 이벤트 객체를 만들어야한다.
WSAEventSelect(socket, event, networkEvents);
FD_ACCEPT: 접속한 클라가 있음. accept
FD_READ: 데이터 수신 가능. recv, recvfrom
FD_WRITE: 데이터 송신 가능. send, sendto
FD_CLOSE: 상대가 접속 종료.
FD_CONNECT: 통신을 위한 연결 절차 완료.
FD_OOB
// 주의사항
WSAEventSelect 함수를 호출하면, 해당 소켓은 자동으로 Non-Blocking 모드로 전환된다.
accept() 함수가 리턴하는 소켓은 listenSocket과 동일한 속성을 갖는다.
- 따라서 clientSocket은 FD_READ, FD_WRITE 등을 다시 등록 필요.
드물게 WSAEWOULDBLOCK 오류가 뜰 수 있으니 예외 처리 필요.
* 이벤트 발생시 적절한 소켓 함수 호출해야함.
- 실패시 다음 동일 네트워크 이벤트가 발생하지 않는다.
ex) FD_READ -> recv() 함수로 수신 -> FD_READ 가능
FD_READ -> recv함수가 없음 -> FD_READ가 다시 발생하지 않음.
WSAWaitForMultipleEvents
- 매개변수
1. event 갯수, event pointer
2. waitAll: 모두 기다림 or 하나만 완료되어도 OK
3. timeout: 정해진 시간이 지나면 타임아웃.
4. fAlertable: 일단은 false
-> return: 완료된 첫 번째 인덱스
https://learn.microsoft.com/ko-kr/windows/win32/api/winsock2/nf-winsock2-wsawaitformultipleevents
WSAWaitForMultipleEvents 함수(winsock2.h) - Win32 apps
지정된 이벤트 개체 중 하나 또는 전부가 신호 상태이거나, 제한 시간 간격이 만료되거나, I/O 완료 루틴이 실행된 경우를 반환합니다.
learn.microsoft.com
WSAEnumNetworkEvents
WSAWairForMultipleEvents의 리턴값으로 완료된 인덱스를 받으면 해당 이벤트를 찾아야한다.
- 매개변수
1. socket
2. eventObject: socket과 연동된 이벤트 객체 핸들을 넘겨주면, 이벤트 객체를 non-signaled 상태로 바꿔준다.
3. networkEvent: 감시하고 있던 네트워크 이벤트 or 오류 정보가 저장된다.
recv length가 -1이면 서버가 열리기 전, 클라이언트가 먼저 접속해서 생긴 것이므로 테스트 환경에서 클라이언트의 접속을 1초 지연시키도록 하면 된다.
코드)
https://github.com/Juzdalua/study-cpp/blob/main/Study/TCP-WSAEvent-NonBlocking-SocketServer.cpp
study-cpp/Study/TCP-WSAEvent-NonBlocking-SocketServer.cpp at main · Juzdalua/study-cpp
Study C++. Contribute to Juzdalua/study-cpp development by creating an account on GitHub.
github.com
'Server > C++' 카테고리의 다른 글
Overlapped 모델 (0) | 2024.08.13 |
---|---|
Blocking & Synchronous (1) | 2024.08.12 |
Select 모델 (0) | 2024.08.07 |
논블로킹 소켓 (Non-Blocking Socket) (0) | 2024.08.07 |
Socket option (0) | 2024.08.06 |