Can I set the timeout for UdpClient in C#?

前端 未结 5 863
不知归路
不知归路 2020-12-09 08:05

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 udpCl

相关标签:
5条回答
  • 2020-12-09 08:12

    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;
    
    ...
    
    0 讨论(0)
  • 2020-12-09 08:12

    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.

    0 讨论(0)
  • 2020-12-09 08:22

    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
    }
    
    0 讨论(0)
  • 2020-12-09 08:22

    There is a ReceiveTimeout property you can use.

    0 讨论(0)
  • 2020-12-09 08:24

    you can do like this:

    udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 5000);
    
    0 讨论(0)
提交回复
热议问题