我正在使用C#UdpClient
类来进行UDP网络连接。有一个UdpClient
对象绑定到固定的本地端口,但不绑定到任何远程端点,因为它需要能够向/从多个不同的端点发送/接收。
我有两个主题:一个用于发送,一个用于接收。现在,当我将数据发送到存在的端点但不监听该端口时,我期望SocketException
。而我确实得到了一个。不幸的是,我的Send
调用不是返回异常,而是Receive
调用。所以在我的发送线程上,我将数据发送到“无效”端点,我的接收线程获得异常。不幸的是,在那一点上,我当然不知道哪个端点导致该异常发生。
在发送之前存储端点,然后在接收线程中访问端点只是等待发生的竞争条件错误。
不幸的是,SocketException
没有给出导致错误的端点。
有什么想法吗?是否有可能在发送线程上抛出异常?
非常感谢帮助。
答案 0 :(得分:3)
当你send()
一个UDP数据包时,它会在线路上消失并且有效地消失。你不应该假设你会得到任何反馈。
有时,如果目的地没有侦听器,目标可能足以发送回ICMP_UNREACH_PORT
消息。然后之间的路由器可能足以将该消息传递给您的操作系统。如果发生这种情况,则会在原始send()
调用返回后很长时间。对于ICMP_UNREACH_PORT
,操作系统通常会对其进行缓存,并在下次向同一目标执行send()
时报告错误。其他ICMP消息(您没有提到您获得的异常)可能会影响其他呼叫。
所以最重要的是,没有人知道何时或是否会报告UDP错误。这取决于很多变量。因此,请准备好处理任何调用的异常,并准备好在没有任何错误报告的情况下消失的数据包。
答案 1 :(得分:0)
我认为这是UDP的预期行为。 UDP send()
不是阻塞操作,因此它不会等待潜在的错误。 (更不用说在发送到具有封闭端口的活动主机时,您不能依赖于可靠接收的错误消息 - 它可能是防火墙,速率限制或因拥塞等原因而丢弃)。 p>
您可以connect()
UDP套接字到特定的远程端点,该端点将分配唯一的端口号,并允许操作系统[最有可能]将该特定端点的错误与任何其他随机主机区分开来。但同样,你不应该依赖于处理这些错误的能力。
在例外中没有更多信息太糟糕了。这似乎是.NET处理UDP套接字的方式的疏忽。根据{{3}},您需要检查异常的ErrorCode并适当地处理documentation。 (在你的情况下,这可能意味着忽略错误。)