프로그래밍/C
윈도우 소켓 ] connect 비동기로 처리하기
eteo
2023. 9. 30. 22:23
논블로킹 소켓으로 설정한 뒤 connect를 시도한다.
connect 함수의 리턴값이 SOCKET_ERROR인 경우, WSAGetLastError()로 오류를 확인하여 WSAEWOULDBLOCK 인 경우 현재 백그라운드에서 연결이 진행중임을 나타낸다.
writeSet에 소켓을 넣고 select 함수를 호출하여 타임아웃 시간 동안 write-ready 상태가 되는지 감지한다.
select() 함수는 오류가 발생한 경우 -1, 타임아웃인 경우 0 그리고 이벤트를 감지한 경우 감지한 소켓 수를 리턴한다.
// 논블로킹 모드로 설정
u_long nonBlockOpt = 1;
if (ioctlsocket(cSocket, FIONBIO, &nonBlockOpt) == SOCKET_ERROR) {
OutputDebugString("ioctlsocket() error.\n");
return false;
}
// 비동기 connect 시도
if (connect(cSocket, (SOCKADDR*)&servInfo, sizeof(servInfo)) == SOCKET_ERROR)
{
// 비동기 connect 작업이 진행중이 아닌 경우
if (WSAGetLastError() != WSAEWOULDBLOCK)
{
OutputDebugString("connect() error");
return false;
}
}
fd_set writeSet;
FD_ZERO(&writeSet);
FD_SET(cSocket, &writeSet);
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
// 1초 동안 연결 상태 모니터링
int result = select(0, NULL, &writeSet, NULL, &timeout);
if (result == SOCKET_ERROR)
{
OutputDebugString("select() error\n");
return false;
}
else if (result == 0)
{
OutputDebugString("select() timeout\n");
return false;
}
else if (!FD_ISSET(cSocket, &writeSet))
{
OutputDebugString("Connection failed!\n");
return false;
}