Can I set the timeout for UdpClient in C#?
I am wondering whether I can set a timeout value for UdpClient receive method.
I want to use block mode, but because sometimes udp will lost 开发者_如何学Pythonpacket, my program udpClient.receive will hang there forever.
any good ideas how I can manage that?
There is a SendTimeout
and a ReceiveTimeout
property that you can use in the Socket
of the UdpClient
.
Here is an example of a 5 second timeout:
var udpClient = new UdpClient();
udpClient.Client.SendTimeout = 5000;
udpClient.Client.ReceiveTimeout = 5000;
...
What Filip is referring to is nested within the socket that UdpClient
contains (UdpClient.Client.ReceiveTimeout
).
You can also use the async methods to do this, but manually block execution:
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
}
There is a ReceiveTimeout property you can use.
Actually, it appears that UdpClient
is broken when it comes to timeouts. I tried to write a server with a thread containing only a Receive which got the data and added it to a queue. I've done this sort of things for years with TCP. The expectation is that the loop blocks at the receive until a message comes in from a requester. However, despite setting the timeout to infinity:
_server.Client.ReceiveTimeout = 0; //block waiting for connections
_server.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 0);
the socket times out after about 3 minutes.
The only workaround I found was to catch the timeout exception and continue the loop. This hides the Microsoft bug but fails to answer the fundamental question of why this is happening.
you can do like this:
udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 5000);
精彩评论