.Net UdpClient
的实现已被破坏,并在文档中假定的行为与其实现的错误方式之间引入了许多严重的难题。特别是,超时不起作用。
// Setup
var udp = new UdpClient();
int timeoutMs = 1000;
udp.ReceiveTimeout(timeoutMs); // Fiction
udp.Connect(new IpEndPoint(IPAddress.Parse(
// Any IP we know has nothing there
"192.168.254.254"), 49999));
udp.Send(new byte[] { 0x00 }, 1);
// Synchronous
udp.Receive(); // Hangs the thread
// Async 1
var iar = udp.BeginReceive(cb, null);
var ip = new IPEndPoint();
udp.EndReceive(iar, ref ip); // Hangs the thread
// Async 2
await udp.ReceiveAsync(); // Hangs the thread
这些不会将线程挂起1000毫秒(1秒),而是将其永久挂起。它只是冻结而死。关于此问题的其他讨论也担心IO搁浅,但在此之上搁浅线程肯定会更糟。
在不稳定的网络/端点情况下使用UdpClient的正确方法是什么(实际上,这是使用任何网络库的唯一方法)?
相关: This answerer found the same problem。
This asker found the same problem。
已接受的答案here提出了一个复杂的.Close()
实现,这隐含地要求每个调用都打开一个新的UdpClient;否则,每个重叠的呼叫都容易受到接收失败的影响。
This one ends up at that conclusion too,但也许不是,.Close()
有害。