본문 바로가기
프로그래밍/C

윈도우 소켓 ] 논블로킹 소켓, ioctlsocket, 소켓 함수의 리턴 조건과 WSAEWOULDBLOCK이 리턴되는 상황

by eteo 2023. 10. 2.

 

socket() 함수로 생성된 소켓은 기본적으로 블로킹 소켓이다. 그리고 블로킹 소켓은 소켓함수 호출 시 조건을 만족할 때까지 리턴하지 않는다.

 

주요 소켓 함수별 리턴 조건은 다음과 같다.

 

  • accpet() : 접속한 클라이언트가 있을때
  • connect() : 서버에 접속 성공했을 때
  • send() : 응용 프로그램이 전송 요청한 데이터를 소켓 송신 버퍼에 모두 복사했을 때
  • recv() : 소켓 수신 버퍼에 도착한 데이터를 응용 프로그램이 제공한 버퍼에 복사했을 때

 

반면 논블로킹 소켓은 소켓함수 호출 시 조건을 만족하지 않아도 함수가 리턴하고 다음 코드가 수행된다.

 

socket()으로 생성된 소켓을 논블로킹 소켓으로 소켓 모드를 변경하는 방법은 다음과 같다.

 

u_long on = 1;
if (ioctlsocket(cSocket, FIONBIO, &on) == SOCKET_ERROR) {
	// 오류처리
}

 

논블로킹 소켓은 소켓 함수 호출시 조건을 만족하지 않으면 오류를 리턴하는데 이때 WSAGetLastError() 함수를 이용해 오류코드를 확인할 필요가 있다. 

 

대개는 WSAEWOULDBLOCK이 리턴되는데 이 오류코드는 비동기 소켓 사용시 다음과 같은 상황에서 반환될 수 있다.

 

 

  • accept() : 클라이언트로부터의 연결 요청이 아직 도착하지 않았을 때
  • connect() : 서버로의 연결이 백그라운드에서 진행중일 때
  • send() : 소켓 송신 버퍼가 가득차서 즉시 보낼 수 없을 때
  • recv() : 데이터가 아직 도착하지 않았는데 읽으려고 시도할 때

이때는 select() 함수를 사용하여 비동기 소켓 이벤트 완료 여부를 확인할 수 있다. (참고로 select()는 입출력함수가 아니라 비동기소켓으로 설정했다고 해서 바로리턴되는게 아니다.)