【问题标题】:Can I set the timeout for UdpClient in C#?我可以在 C# 中为 UdpClient 设置超时吗?
【发布时间】:2011-01-17 21:29:17
【问题描述】:

我想知道是否可以为 UdpClient 接收方法设置超时值。

我想使用阻塞模式,但是因为有时udp会丢包,我的程序udpClient.receive会永远挂在那里。

我有什么好主意吗?

【问题讨论】:

    标签: c# timeout udpclient


    【解决方案1】:

    您可以在UdpClientSocket 中使用SendTimeoutReceiveTimeout 属性。

    以下是 5 秒超时的示例:

    var udpClient = new UdpClient();
    
    udpClient.Client.SendTimeout = 5000;
    udpClient.Client.ReceiveTimeout = 5000;
    
    ...
    

    【讨论】:

    • 这仅在您进行同步发送/接收时有效。对于异步调用,您可以使用 Task.Delay 创建自己的超时,例如Task.WhenAny(udpClient.ReceiveAsync(), Task.Delay(5000));
    • 当然好!我怎么会错过这个简单的解决方案!感谢您的评论 AJ!
    • @AJRichardson 好吧,我认为这不是一个好方法,因为当 timer -ask 完成时,该过程将恢复但 udpClient.ReceiveAsync() 仍将等待.. . 我建议可能是这样的:Task.WaitAny(new[] { udpClient.ReceiveAsync() }, waitTimeOutInMs);
    • @IvandroJao 你是对的,虽然我不知道你的代码能解决这个问题。听起来你应该在超时情况下关闭套接字:见stackoverflow.com/a/12642359/1299394
    【解决方案2】:

    Filip 所指的内容嵌套在 UdpClient 包含的套接字 (UdpClient.Client.ReceiveTimeout) 中。

    您也可以使用异步方法来执行此操作,但手动阻止执行:

    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
    }
    

    【讨论】:

    • 这是很久以前的事了!现在看起来没问题。 WaitOne 还会返回一个结果,您可以使用它来确定它是否超时。
    【解决方案3】:

    实际上,UdpClient 似乎在超时时被破坏了。我试图用一个线程编写一个服务器,该线程只包含一个接收数据并将其添加到队列中。多年来,我一直在使用 TCP 做这类事情。期望是循环在接收时阻塞,直到消息来自请求者。但是,尽管将超时设置为无穷大:

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

    套接字在大约 3 分钟后超时。

    我发现的唯一解决方法是捕获超时异常并继续循环。这隐藏了 Microsoft 错误,但未能回答为什么会发生这种情况的根本问题。

    【讨论】:

    • 我猜有 200000 毫秒左右的内部超时?
    【解决方案4】:

    你可以这样做:

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

    【讨论】:

      【解决方案5】:

      您可以使用 ReceiveTimeout 属性。

      【讨论】:

      • ReceiveTimeout 仅用于同步调用(即:接收方法)
      猜你喜欢
      • 2013-08-15
      • 1970-01-01
      • 2011-02-07
      • 1970-01-01
      • 2017-09-01
      • 2011-07-20
      • 1970-01-01
      • 2019-05-21
      • 1970-01-01
      相关资源
      最近更新 更多