Search

Boost.Asio | UDP 소켓으로 데이터그램 전송 시 system:10054 에러

Date
2024/12/21
category
Boost.Asio
Tags
boost.asio
c++
windows
network

1. UDP 소켓을 사용하는 클라이언트

클라이언트 코드는 위와 같다. 전체적인 코드의 흐름은 UDP 소켓으로 daytime 서버에 데이터그램을 전송한 후 서버가 daytime 정보를 담은 데이터그램을 클라이언트로 보내면 그것을 수신한 후 출력하는 것이다. 만약 서버가 없다면 어떤 문제가 생길까?

2. 서버가 없을 때 출력

receive_from: 현재 연결은 원격 호스트에 의해 강제로 끊겼습니다 [system:10054 at ... in function 'receive_from']
Plain Text
복사
윈도우 환경에서 로컬 호스트로 테스트했을 때 위와 같이 출력된다. receive_from에서 예외가 발생한다. 에러 코드를 보면 system:10054인데, link iconBoost.System: Extensible Error Reporting 이 글을 읽어보면 10054는 OS 레벨에서 반환한 에러 코드를 의미한다는 것을 알 수 있다.

3. 윈도우 소켓 에러 코드

찾아보니 10054는 윈도우 소켓의 에러 코드 중 WSAECONNRESET에러의 값이다. link iconMicrosoftLearnWindows Sockets Error Codes (Winsock2.h) - Win32 apps 에서 에러의 설명을 보면 원격 호스트의 문제로 연결이 끊긴 것이라고 한다. 하지만 여기서 의문이 생긴다. UDP는 TCP와 달리 비연결지향형 프로토콜로 연결이라는 개념이 없다. receive_from에서 애초에 연결이 없는 상태인데 연결을 끊다는 것이 무슨 의미이고 원격 호스트에 문제가 있는지 어떻게 아는 걸까?

4. 패킷 분석

통신 중에 주고받는 패킷을 본다면 어떤 식으로 동작하는지 힌트를 얻을 수 있을 것이라고 생각했다.
Wireshark로 클라이언트 코드를 실행하고 패킷을 캡처했다. DAYTIME 프로토콜 요청을 먼저 보내는데 이것은 send_to를 할 때 전송하는 데이터그램일 것이다. 이후 ICMP 메시지를 받는데 Destination unreachable 타입 메시지를 받는다. 즉 send_to를 했을 때 클라이언트는 데이터그램이 목적지에 도달하지 못 했다는 것을 알게 된다. 윈도우 소켓은 데이터그램을 보냈을 때 Destination unreachable ICMP 메시지를 받으면 데이터그램 수신을 시도할 때 10054 에러가 발생한다는 것을 알 수 있다.

5. 10054 에러를 무시한다면

receive_from을 시도했을 때 10054 에러가 발생하면 receive_from을 다시 시도하도록 코드를 수정했다. 코드를 실행해보니 receive_from 첫 시도에서만 10054 에러가 발생하고 다음 시도에서는 정상적으로 수신 대기를 한다. 하지만 이 코드에서 주의할 점은 서버가 클라이언트의 요청을 받아야 클라이언트에게 응답을 하는 구조인데 만약 클라이언트 send_to 이후에 서버 측 소켓이 생성된다면, 클라이언트는 서버로부터 어떤 응답을 받지 못하고 기다리기만 할 것이다. 최초 send_to 이후로 클라이언트는 추가적인 요청을 하지 않고, 서버는 소켓을 생성하기 전에 클라이언트가 보낸 요청에 대해선 알 수 없기 때문이다.