2010-02-17 18 views
28

Me pregunto si puedo establecer un valor de tiempo de espera para el método de recepción de UdpClient.¿Puedo establecer el tiempo de espera para UdpClient en C#?

Quiero usar el modo de bloque, pero como a veces udp perderá un paquete, mi programa udpClient.receive se bloqueará allí para siempre.

¿Alguna buena idea de cómo puedo hacerlo?

Respuesta

21

Lo que Filip hace referencia está anidado dentro del socket que contiene UdpClient (UdpClient.Client.ReceiveTimeout).

También puede utilizar los métodos asincrónicos para hacer esto, pero manualmente bloque de ejecución:

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

Gracias por la respuesta. – Jack

+0

¡Esto fue hace mucho tiempo! Eso se ve bien ahora. WaitOne también devuelve un resultado que puede usar para determinar si se agotó el tiempo de espera. – weston

2

Hay una propiedad ReceiveTimeout que puede usar.

53

Hay una SendTimeout y una propiedad ReceiveTimeout que se puede utilizar en el Socket del UdpClient.

Aquí se muestra un ejemplo de un 5 segundos de tiempo de espera:

var udpClient = new UdpClient(); 

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

... 
+0

Esto solo funciona si está haciendo un envío/recepción síncrono. Para llamadas ansincrónicas, puede usar 'Task.Delay' para crear su propio tiempo de espera, p. 'Task.WhenAny (udpClient.ReceiveAsync(), Task.Delay (5000))'; –

+0

¡Bien, por supuesto! ¡Cómo extrañé esa solución simple! Gracias por tu comentario AJ! –

3

En realidad, parece que UdpClient se rompe cuando se trata de tiempos de espera. Intenté escribir un servidor con un hilo que solo contenía un Receive que obtenía los datos y los agregaba a una cola. He hecho este tipo de cosas durante años con TCP. La expectativa es que el bucle bloquee en la recepción hasta que llegue un mensaje de un solicitante. Sin embargo, a pesar de marcar el tiempo de espera hasta el infinito:

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

la toma el tiempo de espera después de unos 3 minutos.

La única solución que encontré fue atrapar la excepción de tiempo de espera y continuar el ciclo. Esto oculta el error de Microsoft pero no responde la pregunta fundamental de por qué está sucediendo esto.

+1

Supongo que hay un tiempo de espera interno de 200000 ms o menos? –

1

se puede hacer así:

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