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?
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
}
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;
...
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.
vous pouvez faire comme ça:
udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 5000);
Il existe une propriété ReceiveTimeout que vous pouvez utiliser.