Winsock 错误 10054 (WSAECONNRESET) 与 UDP 到/来自本地主机的“正常”吗?

Posted

技术标签:

【中文标题】Winsock 错误 10054 (WSAECONNRESET) 与 UDP 到/来自本地主机的“正常”吗?【英文标题】:Is Winsock error 10054 (WSAECONNRESET) "normal" with UDP to/from localhost? 【发布时间】:2015-06-10 07:08:14 【问题描述】:

“在单个 Windows PC 上使用 UDP 进行进程间通信可能会出现什么问题?”我想...并着手实施它。

但是,尽管仅发送了数百个字节并且只是非常零星地发送,并且尽管 UDP 被用作无连接协议(使用了sendto() 函数),但我还是被随机出现的错误 10054 - “连接重置”所困扰。我觉得这很令人困惑。是吗:

完全正常,意料之中,在这种情况下......这意味着什么? 完全出乎意料,我可能实现了一些错误 完全出乎意料,所以我应该检查有冲突的软件(例如problems like this) 还有别的吗?

我在某处读到它可能表明另一端没有打开接收端口......但这对我来说更没有意义 - UDP 不是简单地应该发送数据报而不关心会发生什么它?或者当发送到/来自同一台机器(本地主机)上的端口时是否有一些特殊情况?

【问题讨论】:

进一步调查显示,当目标没有任何监听时,Windows 可能会返回 ECONNRESET,而不是 ECONNREFUSED。 看来 Windows recvfrom 文档可能有答案……有待确认。 即使 UDP 是无连接的,也可以在后台发送 ICMP 数据包,让 UDP 发送方知道接收方何时不可用,WinSock 在内部解释这些数据包并可能导致更高级别套接字函数失败。例如,如recvfrom() 所述:“WSAECONNRESET - 远程端执行硬关闭或异常关闭重置了虚拟电路。应用程序应关闭套接字;它不再可用。在UDP-datagram socket 这个错误表明之前的发送操作导致了 ICMP Port Unreachable 消息" ... ... 并为 sendto() 记录:“WSAECONNRESET - 远程端执行硬或异常关闭重置了虚拟电路。对于 UPD 套接字,远程主机无法传递先前发送的 UDP 数据报并以“端口不可达”ICMP 数据包进行响应。应用程序应关闭套接字,因为它不再可用。 谷歌搜索这个错误给了我很多与 ECONREFUSED for UDP 相关的 gitlab / github 问题,很多人想知道在这种情况下“连接”甚至意味着什么......迟到的 ICMP 数据包是如此令人困惑“功能”添加。为什么这个概念甚至属于UDP?如果我想要一个连接的 API,我会使用 TCP 或模拟与 UDP 连接的 API。 【参考方案1】:

在我的具体情况下,我有一个在 localhost 上运行的服务器,监听绑定到特定端口的 UDP 套接字。它还有一个绑定到同一个端口的第二个 UDP 套接字(这在上下文中是有意义的),仅用于发送对在第一个套接字上接收到的数据包的响应。

同样在 localhost 上运行的客户端会创建一个临时套接字,向服务器发送一个数据包,等待响应,然后关闭它们的套接字。客户端的超时时间非常短(出于应用程序特定的原因),如果初始尝试超时,则会重试。

有时会发生的情况是客户端向服务器发送一个数据包,在发送响应之前超时,然后关闭其套接字。然后,服务器将(在侦听套接字上)从客户端接收数据包,并(在发送套接字上)发回响应。但是,Windows “有用”地发回一个 ICMP 响应,说明目标端口上不再有任何套接字侦听。至关重要的是,这个数据包最终被传递到侦听套接字,而不是发送套接字(因为它们都共享相同的端口)。在下一次从服务器上的侦听套接字读取时,会收到 WSAECONNRESET 错误,指示它发送的上一个数据包(实际上是从不同的套接字发送的)未能传递。

在我的例子中,解决方法只是忽略侦听套接字上的WSAECONNRESET 错误。发生此类错误后,侦听套接字继续成功接收其他数据包,而发送失败的数据包传递失败后,发送套接字继续成功发送数据包。

【讨论】:

为什么是第二个套接字?通过原始套接字发送有什么问题? 没什么,除了第二个socket发送的端口有时不同,客户端使用响应的源端口来配置自己。

以上是关于Winsock 错误 10054 (WSAECONNRESET) 与 UDP 到/来自本地主机的“正常”吗?的主要内容,如果未能解决你的问题,请参考以下文章

SSL 错误握手错误 10054“WSAECONNRESET”

烧瓶邮件连接重置错误:[WinError 10054]

操作错误:现有连接被远程主机强行关闭。 (10054)

Python 会话 10054 连接中止错误

UDP错误10054:远程主机强迫关闭了一个现有的连接

由于发生套接字错误(10054)而重试同步-Azure [关闭]