“已连接"UDP 套接字接收 ICMP 端口不可达 [英] "Connected" UDP socket receives ICMP Port Unreachable

查看:27
本文介绍了“已连接"UDP 套接字接收 ICMP 端口不可达的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Based on the premise that UDP is a connectionless protocol I had presumed that whether a host is up or down would be irrelevant.

然而,现在我正在做测试,我发现当我连接"我的 UDP 客户端套接字时,对该套接字的 write 返回一个错误,因为服务器已经发回了一个ICMP 端口不可达错误..

However, now that I'm doing testing I've discovered that when I have "connected" my UDP client socket, a write to that socket returns an error because the server has sent back a ICMP Port Unreachable error ..

连接"UDP 端口的目的(根据 Stevens Unix Network Programming)基本上是缓存路由表中的条目,而不是创建一个新的每个数据包一个,这应该具有性能优势.

The purpose of "connecting" the UDP port (According to Stevens Unix Network Programming) is to basically caches the entry from the routing table, rather than creating a new one for each packet, which is supposed to have performance benefits.

然而,这个 ICMP 数据包导致我丢失客户端套接字,这很烦人.

However, this ICMP packet is causing me to lose my client socket, which is very annoying.

有人可以解释为什么会这样吗?是否有任何已知的解决方法?

Can anybody shed any light on why this could be? Are there any known workarounds?

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

I'm using a 3p java library that doesn't account for this and just disconnects and I'll probably have to hack it to reconnect, but before I do I was kind of hoping there was something I could do at the (Linux) operating system level maybe to prevent this happening ... all investigations into socket options etc. have turned out to be unfruitful.

编辑

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

In summary this isn't possible and fixing the code is the only way to do this.

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

The only possibility appears to be configuring iptables to block the ICMP responses but that's a bit of a sledgehammer to crack this particular nut.

推荐答案

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

Whilst your UDP socket is not strictly "connected", making a connect() call does create local "state" for that socket.

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

This state not only allows the system to cache the current routing entry for the destination, but also means that all subsequent output operations don't need to specify the destination - they'll use the one specified in the connect() call. It also ensures that the kernel will throw away inbound packets destined for your socket that don't come from the "connected" party.

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

This connected state also allows the kernel to deliver errors relating to that socket (signalled via ICMP) to the application - unconnected sockets don't get these - they're "fire and forget".

就您指向我离线的 log4j 代码而言,问题似乎完全出在用户空间代码中.log4j UDPAppender 只是在 write 调用中获得 IOException 时单方面丢弃套接字,并且没有提供检测该条件的方法,因此你可以修复它.

In the case of the log4j code that you've pointed me at offline, the problem appears to be entirely in user space code. The log4j UDPAppender just unilaterally throws away the socket when it gets an IOException on a write call, and provides no means to detect that condition so that you can fix it.

这篇关于“已连接"UDP 套接字接收 ICMP 端口不可达的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆