2

我正在使用 C#UdpClient类来连接 UDP 网络。有一个UdpClient对象,绑定到一个固定的本地端口,但不绑定到任何远程端点,因为它需要能够向/从多个不同的端点发送/接收。

我有两个线程:一个用于发送,一个用于接收。现在,当我将数据发送到存在但不在该端口上侦听的端点时,我期望一个SocketException. 我确实得到了一个。不幸的是,返回异常的不是我Send的调用,而是Receive调用。因此,在我的发送线程上,我将数据发送到“无效”端点,而我的接收线程得到了异常。不幸的是,在那一点上,我当然不知道是什么端点导致了该异常的发生。

在发送之前存储端点,然后在接收线程中访问它只是等待发生的竞争条件错误。

不幸的是,SocketException没有给我导致错误的端点。

有任何想法吗?是否有可能在发送线程上引发异常?

非常感谢您的帮助。

4

2 回答 2

3

当您send()使用 UDP 数据包时,它会通过网络传输并有效地消失。你不应该假设你会得到任何反馈。

有时,如果目的地没有侦听器,目的地可能会好心地发回一条ICMP_UNREACH_PORT消息。介于两者之间的路由器可能会很好地将该消息传递到您的操作系统。如果发生这种情况,那么在您最初的send()呼叫返回之后会很长时间。对于ICMP_UNREACH_PORT,操作系统通常会缓存它并在下次send()您对同一目的地执行 a 时报告错误。其他 ICMP 消息(您没有提到您遇到的异常)可能会影响其他呼叫。

所以底线是不知道何时或是否会报告 UDP 错误。这取决于很多变量。因此,请准备好处理任何呼叫的异常,并准备好数据包消失而不会报告任何错误。

于 2012-01-12T19:49:58.237 回答
0

我认为这是 UDP 的预期行为。UDPsend()不是阻塞操作,因此它不会等待潜在的错误。(更不用说当发送到具有关闭端口的活动主机时,您不能依赖可靠接收到的错误消息 - 它可能是防火墙,速率限制或由于拥塞而被丢弃等)

您可以connect()将 UDP 套接字连接到特定的远程端点,这将分配一个唯一的端口号并允许操作系统 [最有可能] 将来自该特定端点的错误与任何其他随机主机区分开来。但同样,您不应该依赖处理这些错误的能力。

太糟糕了,异常中没有更多信息。这似乎是 .NET 处理 UDP 套接字方式的疏忽。根据文档,您需要检查异常的 ErrorCode 并适当地处理错误。(在您的情况下,这可能意味着忽略错误。)

于 2012-01-11T21:17:19.960 回答