2010-02-17 5 views
28

Mi chiedo se posso impostare un valore di timeout per il metodo di ricezione di UdpClient.Posso impostare il timeout per UdpClient in C#?

Voglio utilizzare la modalità blocco, ma poiché a volte udp smarrirà il pacchetto, il mio programma udpClient.receive si bloccherà lì per sempre.

qualche buona idea come posso gestirlo?

risposta

21

A cui si riferisce Filip è annidato nella presa che contiene UdpClient (UdpClient.Client.ReceiveTimeout).

È inoltre possibile utilizzare i metodi asincroni per fare questo, ma manualmente bloccare l'esecuzione:

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

Grazie per la risposta. – Jack

+0

Questo è stato tanto tempo fa! Adesso sembra ok. WaitOne restituisce anche un risultato che è possibile utilizzare per determinare se è scaduto. – weston

2

Esiste una proprietà ReceiveTimeout che è possibile utilizzare.

53

C'è un SendTimeout e una proprietà ReceiveTimeout che è possibile utilizzare nel Socket del UdpClient.

Ecco un esempio di una di 5 secondi:

var udpClient = new UdpClient(); 

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

... 
+0

Funziona solo se si esegue una trasmissione/ricezione sincrona. Per le chiamate asincrone, puoi usare 'Task.Delay' per creare il tuo timeout, ad es. 'Task.WhenAny (udpClient.ReceiveAsync(), Task.Delay (5000))'; –

+0

Beh, certo! Come ho perso quella soluzione semplice! Grazie per il tuo commento AJ! –

3

realtà, sembra che UdpClient è rotto quando si tratta di timeout. Ho provato a scrivere un server con un thread contenente solo una ricezione che ha ottenuto i dati e li ha aggiunti a una coda. Ho fatto questo genere di cose per anni con TCP. L'aspettativa è che i blocchi di loop in ricezione fino a quando un messaggio arriva da un richiedente. Tuttavia, nonostante l'impostazione del timeout all'infinito:

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

presa di volte dopo circa 3 minuti.

L'unica soluzione che ho trovato è stato catturare l'eccezione di timeout e continuare il ciclo. Questo nasconde il bug di Microsoft, ma non riesce a rispondere alla domanda fondamentale del perché questo sta accadendo.

+1

Immagino che ci sia un timeout interno di 200000 ms o giù di lì? –

1

si può fare in questo modo:

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