web-dev-qa-db-fra.com

Puis-je définir le délai d'expiration pour UdpClient en C #?

Je me demande si je peux définir une valeur de délai d'attente pour la méthode de réception UdpClient.

Je veux utiliser le mode bloc, mais parce que parfois udp perdra des paquets, mon programme udpClient.receive y restera pour toujours.

des bonnes idées pour gérer ça?

35
Jack

Ce à quoi Filip fait référence est imbriqué dans le socket que contient UdpClient (UdpClient.Client.ReceiveTimeout).

Vous pouvez également utiliser les méthodes asynchrones pour ce faire, mais bloquer manuellement l'exécution:

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
}
29
Brad Nabholz

Il existe une propriété SendTimeout et une propriété ReceiveTimeout que vous pouvez utiliser dans le Socket du UdpClient.

Voici un exemple de délai d'expiration de 5 secondes:

var udpClient = new UdpClient();

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

...
60
sep15ms

En fait, il semble que UdpClient soit rompu en ce qui concerne les délais d'attente. J'ai essayé d'écrire un serveur avec un thread contenant uniquement une réception qui a obtenu les données et les a ajoutées à une file d'attente. J'ai fait ce genre de choses pendant des années avec TCP. L'attente est que la boucle se bloque à la réception jusqu'à ce qu'un message arrive d'un demandeur. Cependant, malgré la définition du délai à l'infini:

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

la prise s'éteint après environ 3 minutes.

La seule solution de contournement que j'ai trouvée était d'attraper l'exception de délai d'expiration et de continuer la boucle. Cela masque le bogue Microsoft mais ne répond pas à la question fondamentale de savoir pourquoi cela se produit.

4
Pierre

vous pouvez faire comme ça:

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

Il existe une propriété ReceiveTimeout que vous pouvez utiliser.

2
Filip Ekberg