【发布时间】:2011-01-17 21:29:17
【问题描述】:
我想知道是否可以为 UdpClient 接收方法设置超时值。
我想使用阻塞模式,但是因为有时udp会丢包,我的程序udpClient.receive会永远挂在那里。
我有什么好主意吗?
【问题讨论】:
我想知道是否可以为 UdpClient 接收方法设置超时值。
我想使用阻塞模式,但是因为有时udp会丢包,我的程序udpClient.receive会永远挂在那里。
我有什么好主意吗?
【问题讨论】:
您可以在UdpClient 的Socket 中使用SendTimeout 和ReceiveTimeout 属性。
以下是 5 秒超时的示例:
var udpClient = new UdpClient();
udpClient.Client.SendTimeout = 5000;
udpClient.Client.ReceiveTimeout = 5000;
...
【讨论】:
Task.Delay 创建自己的超时,例如Task.WhenAny(udpClient.ReceiveAsync(), Task.Delay(5000));
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
}
【讨论】:
实际上,UdpClient 似乎在超时时被破坏了。我试图用一个线程编写一个服务器,该线程只包含一个接收数据并将其添加到队列中。多年来,我一直在使用 TCP 做这类事情。期望是循环在接收时阻塞,直到消息来自请求者。但是,尽管将超时设置为无穷大:
_server.Client.ReceiveTimeout = 0; //block waiting for connections
_server.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 0);
套接字在大约 3 分钟后超时。
我发现的唯一解决方法是捕获超时异常并继续循环。这隐藏了 Microsoft 错误,但未能回答为什么会发生这种情况的根本问题。
【讨论】:
你可以这样做:
udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 5000);
【讨论】:
您可以使用 ReceiveTimeout 属性。
【讨论】: