【问题标题】:Receiving ICMP Host Unreachable message on UDP socket in Python在 Python 中的 UDP 套接字上接收 ICMP Host Unreachable 消息
【发布时间】:2025-11-24 00:10:01
【问题描述】:

我正在 Linux 2.6.38 上用 Python 2.7 编写一个简单的 UDP 聊天服务器。

如何读取主机(客户端)在将 UDP 段发送到无法访问的服务器时收到的 ICMP 错误消息?

我试过了

sockFd.setsockopt( socket.IPPROTO_IP, socket.IP_RECVERR, 1 ) 

但是 socket.IP_RECVERR 没有在 socket 模块中定义。

我尝试在 sockFd.recvfrom 上使用超时并再次执行 sendto 但这没有帮助。是否有 API 可以读取主机收到的 ICMP 错误?

【问题讨论】:

    标签: python linux sockets udp icmp


    【解决方案1】:

    这个问题有点老了,但我会回答它,因为我遇到了同样的问题。

    常量IP_RECVERR是在“IN”模块中定义的,所以下一条语句应该可以完成这项工作:

    import socket
    import IN
    sockFd.setsockopt( socket.IPPROTO_IP, IN.IP_RECVERR, 1 )
    

    【讨论】:

      【解决方案2】:

      ICMP 错误基本上是无用的。如果你收到一个错误,那并不能保证另一端没有收到数据包。如果您没有收到错误,则不能确保另一端确实收到了数据包。所以几乎没有理由费心去做这件事。

      如果您告诉我们更多关于您认为需要这样做的原因,我们可以告诉您应该怎么做。

      【讨论】:

      • +1。此外,并非所有主机都会发送 ICMP。 NAT 和防火墙也可以静默丢弃数据包。
      • 我已经在服务器上设置了 iptables,这样它就可以为它收到的任何 UDP 消息发回 ICMP 主机不可达消息。所以,我试图在客户端验证这种行为。
      • 那没有回答最初的问题。你如何应对socket.IP_RECVERR的缺失?
      • @RickyRobinson 你不需要它们——如果你得到它们,它们将毫无用处。你为什么认为你会这样做?
      • @RickyRobinson 这超出了这个问题的范围。但在这种情况下,您仍然打开了一个原始套接字,因此您可以侦听原始 ICMP 错误。
      最近更新 更多