Computer Science 기본 지식/소켓 프로그래밍

[TCP/IP 소켓 프로그래밍] WSACreateEvent()와 WSAEventSelect()

로파이 2021. 8. 21. 17:16
WSAEVENT WSAAPI WSACreateEvent();

WSACreateEvent : 수동 리셋 모드의 이벤트 객체를 반환하며 초기 상태는 비신호 상태이다. 이름이 없기 때문에 자식프로세스에서 상속할 수 없다.

 

WSASetEvent, WSAResetEvent, WSACloseEvent 등으로 이벤트 객체의 신호 발생과 객체 소멸을 발생시킬 수 있다.

int WSAAPI WSAEventSelect(
  SOCKET   s,
  WSAEVENT hEventObject,
  long     lNetworkEvents
);

특정 소켓과 WSAEVENT 객체를 연결시키고 소켓에 대한 네트워크 이벤트가 감지되었을 때 해당 이벤트 오브젝트를 신호상태로 만들어준다. lNetworkEvents 인자에 관찰하고자하는 네트워크 이벤트 종류를 담는다. (FD_READ | FD_WRITE | FD_CONENCT | FD_ACCEPT) 등

int WSAAPI WSAEnumNetworkEvents(
  SOCKET             s,
  WSAEVENT           hEventObject,
  LPWSANETWORKEVENTS lpNetworkEvents
);

WaitForXXX를 통해 해당 이벤트가 발생했음을 감지하고 위 함수를 통해 어떤 이벤트가 발생했는지 알 수 있다.

// 이벤트 감지
eventID = ::WaitForSingleObject(m_hSelectEvent, INFINITE);

// 소켓 이벤트가 발생했을 때 받아온다.
// m_SelectEvent에서 네트워크 이벤트를 가져온다.
eventID = WSAEnumNetworkEvents(m_hSocket, m_hSelectEvent, &networkEvents);

// 만약 eventID가 SOCKET_ERROR일 경우 무엇이 잘못된 것이므로 스레드를 종료한다.
if (eventID == SOCKET_ERROR)
{
	LOG_OUT("Event ID is Error : %s\n", GetLastErrorMsg().c_str());
	return;
}
else
{
	// Connect 이벤트가 발생했을 경우
	if (networkEvents.lNetworkEvents & FD_CONNECT)
	{
		// 가상 함수를 호출한다.
		OnIoConnected();

		if (networkEvents.iErrorCode[FD_CONNECT_BIT])
			return;
	}

	// 사용하지 않는 이벤트
	else if (networkEvents.lNetworkEvents & FD_WRITE)
	{
		// OnIoWrite();
	}

	// Read 이벤트
	else if (networkEvents.lNetworkEvents & FD_READ)
	{
		OnIoRead();
	}

	// Disconnect 이벤트
	else if (networkEvents.lNetworkEvents & FD_CLOSE)
	{
		OnIoDisconnected();
		return;
	}
}