728x90

손실된 패킷에 대해서 처리하는 가장 간단한 방법은 TCP의 패킷 재전송 시스템과 흡사한 장치를 설계하는 것이다. 원격 호스트로 무사히 도착한 패킷들에 대해서 반환 패킷을 전송하도록 구현한다. 예정된 반환 패킷이 일정 시간 내로 도착하지 않는다면, 원래의 패킷을 재전송하도록 한다.

UDP 재전송 장치를 구현하는 방법은 크게 두 가지이다.

 

비동기 소켓과 타이머 객체

이 기법은 블록을 걸지 않으면서 들어오는 패킷을 대기할 수 있는 비동기 소켓을 필요로 한다. 소켓이 비동기 읽기 상태로 설정되었으면, Timer 객체가 설정된다. 비동기 읽기 작업이 완료되기 전에 Timer 객체가 울리면 재전송을 명령하게 된다.

 

동기 소켓과 소켓 타임아웃 설정

이 장치는 SetSocketOption() 메소드를 사용하여 구현한다.

 

 

-소켓 타임아웃 사용

앞에서 살펴보았듯이, ReceiveFrom() 메소드는 블로킹 함수이다. 이러한 특성은 패킷의 수신이 불확실한 UDP 프로그램에서는 매우 치명적인 문제가 된다. 데이터 패킷이 수신되지 않으면 프로그램은 영원히 멈추게 되고 결국은 이에 지친 고객이 수동으로 프로그램을 종료할 수 밖에 없다.

기본적으로 ReceiveFrom() 메소드는 무기한의 블록을 걸어 데이터를 대기한다. 그러나 이러한 설정은 소켓 옵션에서 제어할 수 있다. ReceiveFrom()메소드가 데이터를 대기하는 시간을 조정할 수 있으며, 대기하고 있는 상태를 종료시킬 수도 있다. SetSocketOption() 메소드를 통해 생성한 소켓 객체에 여러 소켓 옵션을 설정할 수 있는데, 이 중에는 ReceiveTimeout 이라는 옵션이 있다. 이는 일정 시간동안 들어올 패킷을 대기하면서 그 시간이 초과하면 소켓이 타임아웃을 발생하도록 한다.

 

 SetSocketOption(SocketOptionLevel so, SocketOptionName sn, int value)

 

SocketOptionLevel은 구현할 소켓 옵션의 종류를 나타낸다. SocketOptionName 은 설정할 특정 옵션을 정의하며, 마지막 파라미터(int value)는 옵션의 설정값을 나타낸다. 옵션을 지정하기 위해서는 다음과 같은 형태로 메소드를 사용한다.

 

server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 3000);

 

정수 파라미터는 소켓이 타임아웃을 신호하기까지의 대기 시간(milliseconds)이다.

다음은 원래의 ReceiveTimeout 값을 소켓으로부터 조사해서 표시하며, 이를 3초로 설정하는 예제이다.

 

int sockopt = (int)server.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout);

Console.WriteLine("Default timeout : {0}", sockopt);

 

server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 3000);

 

GetSocketOption() 메소드는 Object 객체를 반환하기 때문에 실제로 이 값을 보기 위해서는 이를 정수의 형태로 캐스팅해주어야 한다.

 

 

ReceiveTimeout 값에 도달하게 되면, 소켓은 데이터를 더 이상 대기하지 않고 SocketException를 발생시킨다. 타임아웃 기능을 효과적으로 사용하기 위해서는 이 SocketException을 포착할 코드를 작성해야 한다.

 

-예외상황 포착

소켓이 타임아웃 값에 도달하면 SocketException을 발생시키는 것을 확인했으니, 이 예외상황을 포착하여 사용자에게 알려 몇가지 대안을 제시해야 한다.

 

 

통신 초기에 서버로부터 아무런 패킷을 수신하지 못했다면, 서버가 존재하지 않는 것으로 간주하고 프로그램을 종료한다.

예외상황을 포착하는 기법은 모든 ReceiveFrom() 메소드가 성공했는지를 분석하여 실패하는 경우는 고객에게 통보를 한다. 비록 좋은 기능이지만, 원래의 메시지가 목적지에 제대로 도착하지 못한 문제 해결에는 그다지 도움이 되지 않는다. 이 때 프로그램으로 하여금 원래의 메시지를 재전송하도록 하는 것이 좋은 해결 방법이다.

출처 : http://kym2732.blog.me/121029405

728x90

'Network' 카테고리의 다른 글

SKT 포트포워딩 안되는 경우  (0) 2021.04.30
다중화 기술  (0) 2014.11.30
MAC, IP ADDRESS  (0) 2014.11.13
3 way handshaking  (0) 2014.11.13
TCP Tahoe  (0) 2014.10.27

+ Recent posts