我可以在 C# 中为 UdpClient 设置超时吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2281441/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 01:00:33  来源:igfitidea点击:

Can I set the timeout for UdpClient in C#?

c#timeoutudpclient

提问by Hyman

I am wondering whether I can set a timeout value for UdpClient receive method.

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

I want to use block mode, but because sometimes udp will lost packet, my program udpClient.receive will hang there forever.

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

any good ideas how I can manage that?

有什么好主意我该如何管理?

采纳答案by Brad Nabholz

What Filip is referring to is nested within the socket that UdpClientcontains (UdpClient.Client.ReceiveTimeout).

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

You can also use the async methods to do this, but manually block execution:

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

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
}

回答by Filip Ekberg

There is a ReceiveTimeout property you can use.

您可以使用 ReceiveTimeout 属性。

回答by sep15ms

There is a SendTimeoutand a ReceiveTimeoutproperty that you can use in the Socketof the UdpClient.

有一个SendTimeoutReceiveTimeout属性,您可以在使用SocketUdpClient

Here is an example of a 5 second timeout:

以下是 5 秒超时的示例:

var udpClient = new UdpClient();

udpClient.Client.SendTimeout = 5000;
udpClient.Client.ReceiveTimeout = 5000;

...

回答by Pierre

Actually, it appears that UdpClientis 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:

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

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

the socket times out after about 3 minutes.

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

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.

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

回答by Elyas Nategh

you can do like this:

你可以这样做:

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