【发布时间】:2017-02-03 21:41:52
【问题描述】:
基于 UDP 是一种无连接协议的前提,我假设主机是启动还是关闭是无关紧要的。
但是,现在我正在进行测试,我发现当我“连接”我的 UDP 客户端套接字时,该套接字的 write 会返回错误,因为服务器已发回 ICMP Port Unreachable 错误。 .
“连接”UDP 端口的目的(根据 Stevens Unix Network Programming)基本上是缓存路由表中的条目,而不是创建一个新的每个数据包一个,这应该具有性能优势。
但是,这个 ICMP 数据包导致我丢失了我的客户端套接字,这很烦人。
任何人都可以解释为什么会这样吗?是否有任何已知的解决方法?
我正在使用一个 3p java 库,它不考虑这个问题,只是断开连接,我可能不得不破解它才能重新连接,但在我这样做之前,我有点希望我能在(Linux) 操作系统级别可能会防止这种情况发生……所有对套接字选项等的调查都没有结果。
编辑
总而言之,这是不可能的,修复代码是做到这一点的唯一方法。
似乎唯一的可能性是配置 iptables 来阻止 ICMP 响应,但这有点像大锤来破解这个特殊的坚果。
【问题讨论】:
-
也就是说,我不确定我是否理解您的问题。您尝试将套接字连接到不可用的端点,并收到 ICMP 错误。当您尝试
write时,为什么不会收到错误消息? -
因为它是 connectionless - 实际上,如果我没有连接,那么我就不会收到此错误。不要被连接这个词误导,只是因为这不是它在数据报上下文中的含义。就像我说的那样,史蒂文斯甚至显得很困惑。
-
@EJP 在与 OP 的进一步讨论中,根本问题是 log4j 中
UDPAppender的一个非常糟糕的实现,它使用连接的套接字,但如果远端消失,则无法提供恢复方法。 bz.apache.org/bugzilla/show_bug.cgi?id=57891 -
下一段中的文字似乎不正确。它说“recvfrom 可以返回的唯一信息是一个errno 值;recvfrom 无法返回错误数据报的目标IP 地址和目标UDP 端口号”。这很奇怪,因为这正是
address字段可以用于的用途,似乎 BSD 人员决定在出现 ICMP 错误时不填写它。 WRS 已不在我们身边,但我认识其中一位合著者,可以向他询问。
标签: java linux sockets udp icmp