2010-02-17 2 views
28

UdpClient 수신 방법에 대한 시간 초과 값을 설정할 수 있는지 궁금합니다.C#에서 UdpClient의 시간 제한을 설정할 수 있습니까?

차단 모드를 사용하고 싶지만 때때로 udp가 패킷을 잃어 버리게되어 내 프로그램 udpClient.receive가 영원히 중단됩니다.

내가 관리 할 수있는 좋은 아이디어가 있습니까?

답변

21

Filip이 참조하는 것은 UdpClient에 (UdpClient.Client.ReceiveTimeout)이 포함 된 소켓 내에 중첩되어 있습니다.

당신은이 작업을 수행 할 비동기 방법을 사용하지만, 수동으로 실행을 차단할 수 있습니다

var timeToWait = TimeSpan.FromSeconds(10); 

var udpClient = new UdpClient(portNumber); 
var asyncResult = udpClient.BeginReceive(null, null); 
asyncResult.AsyncWaitHandle.WaitOne(timeToWait); 
if (asyncResult.IsCompleted) 
{ 
    try 
    { 
     IPEndPoint remoteEP = null; 
     byte[] receivedData = udpClient.EndReceive(asyncResult, ref remoteEP); 
     // EndReceive worked and we have received data and remote endpoint 
    } 
    catch (Exception ex) 
    { 
     // EndReceive failed and we ended up here 
    } 
} 
else 
{ 
    // The operation wasn't completed before the timeout and we're off the hook 
} 
+1

감사합니다. – Jack

+0

오래 전 일이었습니다! 이제 괜찮아 보입니다. 또한 WaitOne은 시간 초과 여부를 확인하는 데 사용할 수있는 결과를 반환합니다. – weston

2

사용할 수있는 ReceiveTimeout 속성이 있습니다.

53

SendTimeout하고 UdpClientSocket에서 사용할 수있는 ReceiveTimeout 특성이 있습니다.

var udpClient = new UdpClient(); 

udpClient.Client.SendTimeout = 5000; 
udpClient.Client.ReceiveTimeout = 5000; 

... 
+0

이것은 동기식 보내기/받기를 수행하는 경우에만 작동합니다. 비동기 호출의 경우,'Task.Delay'를 사용하여 자신의 타임 아웃을 생성 할 수 있습니다. 'Task.WhenAny (udpClient.ReceiveAsync(), Task.Delay (5000))'; –

+0

물론! 어떻게 그 간단한 해결책을 놓쳤습니까! 귀하의 코멘트 주셔서 감사 AJ! –

3

사실, 시간 제한에 관해서 UdpClient가 파손 된 것으로 나타난다 : 여기서

는 5 초 초과의 예이다. 데이터를 가져 와서 큐에 추가 한 Receive 만 포함하는 서버로 서버를 작성하려고했습니다. TCP로 수년간 이런 일을 해왔습니다. 예상은 요청자가 메시지를 수신 할 때까지 루프에서 수신을 차단하는 것입니다. 그러나 제한 시간을 무한대로 설정하더라도 : 약 3 분 후에 소켓 시간 초과가 발생합니다.

유일한 대안은 타임 아웃 예외를 catch하고 루프를 계속하는 것입니다. 이것은 Microsoft 버그를 숨기지 만 근본적인 문제에 대한 대답은 실패합니다.

+1

내부 시간 초과가 200000ms 정도입니까? –

1

다음과 같이 할 수 있습니다 답장을

udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 5000); 
관련 문제