UDP sendto 永远不会失败

Posted

技术标签:

【中文标题】UDP sendto 永远不会失败【英文标题】:UDP sendto never fails 【发布时间】:2015-10-19 06:50:51 【问题描述】:

我的应用程序不断地向不同的主机发送 UDP 数据包。当主机处于活动状态时,UDP 数据包到达主机,sendto 函数返回发送给它的字节数。但是当主机宕机(电缆拔出或重置)时,sendto 函数不会发送 UDP 数据包,但仍会返回缓冲区中的字节数。不是发送 UDP 数据包,而是发送 ARP 数据包来查找主机。为什么sendto 函数不返回 SOCKET_ERROR? WSAGetLastError 函数也返回 0。如何在向无法访问的主机发送 UDP 数据包时发现错误?

附:我的操作系统是 Winodws 7 x64,我的应用程序是原生 C++ 和 64 位。

【问题讨论】:

你尝试过哪些失败案例?只是拔掉电缆? 当发现错误时,返回任何东西都为时已晚。 【参考方案1】:

你的问题的标题——“UDP sendto never failed”——是对 UDP 的一个很好的总结。

这就是 UDP 的工作原理 - UDP 不在乎目的地是否可达。 当数据包离开您的应用程序时,UDP sendto“成功”;就 UDP 而言,它甚至不需要离开您的计算机。

ARP 包是您的计算机尝试找到到达主机的方法,但此时 sendto 已经“成功”。

如果您想要一个可靠的协议,UDP 不是您想要的。

【讨论】:

你是对的,但是有什么方法可以查出我的数据包没有离开计算机,而我的操作系统正在尝试通过发送 ARP 数据包来查找主机? @MustafaChelik 我怀疑是否存在,但可能有一些特定于 Windows 的东西可以用来代替套接字。使用适合您目的的协议,或者在 UDP 之上实现一个协议,可能是一个更好的主意。【参考方案2】:

UDP sendto() 不可能返回这种性质的错误,除非您通过连接的 UDP 套接字发送,在这种情况下,您可能在后续发送时收到错误。

【讨论】:

以上是关于UDP sendto 永远不会失败的主要内容,如果未能解决你的问题,请参考以下文章

@SendTo Annotation 对于 ActiveMQ 静默失败

一旦 API 失败,协程永远不会调用 API

如果一个 I/O 函数不能因 EINTR 而失败,这是不是意味着它永远不会阻塞?

关于UDP数据报引发“异步错误”的疑问

boost::async_write 在写入一段时间后失败

(十四)UDP协议的两个主要方法sendto和recvfrom详解