首页 文章

“已连接”UDP套接字接收ICMP端口无法访问

提问于
浏览
2

基于UDP是无连接协议的前提,我假设主机是启动还是关闭都是无关紧要的 .

但是,现在我发现当我有"connected"我的UDP客户端套接字时,该套接字的 write 会返回错误,因为服务器已发送回ICMP端口无法访问错误 .

UDP端口(根据Stevens Unix网络编程)的目的是基本缓存来自路由表的条目,而不是为每个数据包创建一个新的数据包,这应该具有性能优势 .

但是,这个ICMP数据包导致我丢失了我的客户端套接字,这非常烦人 .

任何人都可以阐明为什么会这样吗?有没有已知的解决方法?

我正在使用一个3p的java库,不考虑这个,只是断开连接,我可能不得不破解它重新连接,但在我做之前,我有点希望有一些我可以做的事情(Linux)操作系统级别可能是为了防止这种情况发生...所有对套接字选项等的调查都证明是无用的 .

编辑

总之,这是不可能的,修复代码是唯一的方法 .

唯一的可能性似乎是配置iptables来阻止ICMP响应,但这是一个破解这个特殊坚果的大锤 .

2 回答

  • -2

    虽然您的UDP套接字不是严格的"connected",但进行 connect() 调用会为该套接字创建本地"state" .

    此状态不仅允许系统缓存目标的当前路由条目,还意味着所有后续输出操作都不会使用 connect() 调用中指定的操作 . 它还确保内核将丢弃发往您的套接字的入站数据包,这些数据包不是来自"connected"方 .

    这种连接状态还允许内核将与该套接字相关的错误(通过ICMP发出信号)传递给应用程序 - 未连接的套接字不会得到这些 - 它们“一劳永逸” .

    对于您在离线时指向我的log4j代码,问题似乎完全在用户空间代码中 . log4j UDPAppender 只是在 write 调用时获得 IOException 时单方面抛出套接字,并且无法检测到该条件以便您可以修复它 .

  • 3

    好吧, UDP 位于 IP 之上 . 你得到的信息来自那一层 . 见https://en.wikipedia.org/wiki/User_Datagram_Protocolhttps://en.wikipedia.org/wiki/Internet_Control_Message_Protocol

    所以从某种意义上来说它没有连接,你没有持久的隧道,因此不能保证你的数据包按顺序到达,以及东西 . 或者,如果出现错误,您不一定会立即认出 .

    但是你仍然需要能够连接到某些东西,首先 . 它只发生在较低的层次上 .

    但是内核仍然会跟踪套接字,所以它可能会通知你它收到的ICMP数据包,比如说路由器的路由器 . 关键是,ICMP是下面的一层 .

    更新:顺便说一句,我认为,你可以反过来解决这个问题 . 你的路由器或其他任何东西都可以忽略这样一个事实:它不知道将数据包转发到哪里,只是默默地丢弃数据包,而不是回复ICMP错误消息 .

相关问题