Coding Memo

[Winsock] 에러 메모 모음집 본문

메모

[Winsock] 에러 메모 모음집

minttea25 2024. 3. 25. 23:31

문제 상황은 내 개인적인 상황에 해당한다.
엄청 복잡한 문제는 아니지만, 같은 문제를 발생시키는 일이 없도록 기록하려고 작성했다.

(계속 추가...)


ConnectEx - WSAEINVAL (10022)

  • 에러 내용: ConnectEx를 호출할 소켓이 바인딩 되어 있지 않거나 수신 대기 중일 때 발생
  • 문제 상황: ConnectEx 호출 시 발생한 에러
  • 에러 이유: ConnectEx의 첫번째 인자인 소켓이 bind되어 있지 않은 소켓이어서 나타난 에러
  • 해결: ::bind()를 통해 소켓에 로컬 주소와 포트를 바인딩 해준 후, ConnectEx함수를 호출했음
  • 참고: https://learn.microsoft.com/ko-kr/windows/win32/api/mswsock/nc-mswsock-lpfn_connectex#syntax

 

WSASend, WSARecv - WSAENOTCONN (10057)

  • 에러 내용: 말 그대로 소켓이 연결되어 있지 않은 경우에 발생
  • 문제 상황: Connector로 서버에 연결 후에 WSASend와 WSARecv 호출 시에 발생하였음
  • 에러 이유: WSASend와 WSARecv에 사용된 소켓이 연결된 소켓이 아니었음. (Connector에서 연결이 형성된 소켓에 대해 Session이 가지고 있는 소켓이 참조를 하지 않고 있었다.)
  • 해결: 연결된 소켓을 Session에서도 가지고 있는 소켓 (SOCKET 자체가 포인터이다!)이 참조하도록 하여 해결.

 

WSAEADDRINUSE (10048)

  • 에러 내용: 말 그대로 소켓에 연결된 주소 및 포트가 이미 사용중일 때 발생
  • 문제 상황: 이미 accept 대기 중인 주소와 포트에 대해서 다시 새롭게 소켓을 바인딩 하려 할 때 발생하였음
  • 에러 이유: 이전 서버 프로그램이 제대로 종료되지 않거나, 아직 실행중일 때, 같은 프로그램으로 같은 위치(주소 및 포트)에 소켓을 바인딩 하려고 해서 발생
  • 해결: 기존 사용중인 소켓을 정리하거나, 사용중인 프로그램을 완전히 종료하여 해결. 추가적으로 프로그램이 정상적으로 종료되지 않았을 때, 해당 소켓 정리가 지연될 수도 있으니 유의하자.

 

WSAECONNREFUSED (10061)

  • 에러 내용: 연결하려는 사이드에서 연결을 거부했을 때 나타나는 에러
  • 문제 상황: 클라이언트에서 서버에 접속하려고 했으나, ConnectEx가 실패하고 에러 코드가 10061이였음
  • 에러 이유: 문서의 설명에도 나와 있듯이 서버에서 1)연결을 진짜로 거부했거나 2)연결하려는 포인트가 닫혀있을 때 나타남. 나의 경우도 서버에서 바인드를 실패하여 listen 상태까지 가지 못하여, 클라이언트가 연결 거부 당했던 것이였음
  • 해결: 서버에서 바인드 및 listen이 제대로 되는지 확인하자.

 

WSAEAFNOSUPPORT (10061)

  • 에러 내용: 주소 타입과 프로토콜 타입이 호환이 안되는 경우 발생
  • 문제 상황: 서버 사이드에서 bind가 실패하고 10061 에러가 발생
  • 에러 이유: 단순히 보면 주소와 프로토콜 타입이 호환이 안되서 발생한 문제로 볼 수 있지만, 나의 경우는 SOCKADDR_IN 타입의 주소를 reinterpret_cast<const SOCKADDR*>을 하는데에 sockaddr의 주소(참조)를 넣어서, 캐스팅이 이상하게되어 아예 주소를 SOCKADDR_IN*으로 읽지 못하여서 발생한 에러 였음. (즉, 주소와 프로토콜 사이의 호환 문제라기보다는 주소가 아예 잘못되어서 호환 되는지 조차 모르기 때문에 에러가 난 것이었음.
  • 해결: 캐스팅을 제대로 하자... (SOCKADDR_IN*으로 인자를 받았으면, 어차피 const SOCKADDR_IN*으로 똑같이 캐스팅하는 것이므로 그대로 쓰면 되었었다.)
static bool Bind(Socket listenSocket, SOCKADDR_IN* sockaddr)
{
	const int32 res = ::bind(listenSocket, reinterpret_cast<const SOCKADDR*>(sockaddr), sizeof(SOCKADDR_IN));
	...
}

//sockaddr 대신 &sockaddr을 사용해서 에러가 발생