简体   繁体   中英

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 packet, 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
}

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.

您可以使用一个ReceiveTimeout属性。

您可以这样:

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

Since I don't have a reputation of 50, I'm not allowed to comment directly. Nevertheless, I would like to note that the best post and its code, is not a solution. Because the BeginReceive always needs an EndReceive, because otherwise after hundreds of requests, the BeginReceive queue overflows, this is not a solution. If one uses however an EndReceive for the block (Which is unfortunately needed), the call blocks, which means at the end that one has no Timeout. In this respect, Brad Nebholz's code is unfortunately infunctional.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM