2010-02-17 15 views
28

UdpClient alma yöntemi için bir zaman aşımı değeri ayarlayıp ayarlayamayacağımı merak ediyorum.C# içinde UdpClient için zaman aşımı ayarlayabilir miyim?

Blok modunu kullanmak istiyorum, ancak bazen udp paketi kaybedeceğinden, udpClient.receive programım sonsuza kadar orada kalıyor.

İyi fikirleri nasıl yönetebilirim?

cevap

21

Filip ifadesinin anlamı, UdpClient'un (UdpClient.Client.ReceiveTimeout) numaralı yuvada yer almaktadır.

Ayrıca bunu yapmak için zaman uyumsuz yöntemleri kullanın, fakat manuel yürütme engelleyebilirsiniz:

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

teşekkür ederiz. – Jack

+0

Bu uzun zaman önceydi! Bu şimdi iyi görünüyor. WaitOne ayrıca zaman aşımına uğradığını belirlemek için kullanabileceğiniz bir sonuç döndürür. – weston

2

Kullanabileceğiniz bir ReceiveTimeout özelliği vardır.

53

bir SendTimeout ve UdpClient arasında Socket kullanabileceğiniz bir ReceiveTimeout özellik yoktur.

var udpClient = new UdpClient(); 

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

... 
+0

Bu yalnızca senkronize bir gönderme/alma yapıyorsanız çalışır. Eşzamansız çağrılar için, kendi zaman aşımınızı oluşturmak için 'Task.Delay' kullanabilirsiniz. Task.WhenAny (udpClient.ReceiveAsync(), Task.Delay (5000)) '; –

+0

Elbette! Bu basit çözümü nasıl özledim? Yorumunuz için teşekkürler AJ! –

3

Aslında o zaman aşımları geldiğinde UdpClient kırık olduğunu görüntülenir: Burada

bir 5 saniye zaman aşımı örneğidir. Verileri aldım ve bir sıraya ekleyen sadece bir Alma içeren bir iş parçacığı ile bir sunucu yazmaya çalıştım. TCP ile yıllarca böyle şeyler yaptım. Beklenti, döngü bir istekte bulunan bir mesaj gelene kadar almanın blokları. Ancak, sonsuza zaman aşımını ayarlama rağmen:

_server.Client.ReceiveTimeout = 0; //block waiting for connections 
_server.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 0); 

soket kez yaklaşık 3 dakika sonra.

Bulduğum tek geçici çözüm, zaman aşımı istisnasını yakalamak ve döngüye devam etmekti. Bu Microsoft hatasını gizler, ancak bunun neden oluştuğuna dair temel soruyu yanıtlayamaz.

+1

Sanırım 200000 ms'lik dahili bir zaman aşımı var mı? –

1

böyle yapabilirsiniz: cevap için

udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 5000); 
İlgili konular