1

Pyzor使用 UDP/IP 作为通信协议。我们最近将公共服务器切换到一台新机器,并开始收到许多超时的报告。我发现如果我将查询的 IP 从 更改为 ,我可以解决eth0:1问题eth0

我可以用一个简单的例子重现这个问题:

这是服务器代码:

#! /usr/bin/env python

import SocketServer

class RequestHandler(SocketServer.DatagramRequestHandler):
    def handle(self):
        print self.packet
        self.wfile.write("Pong")

s = SocketServer.UDPServer(("0.0.0.0", 24440), RequestHandler)
s.serve_forever()

这是客户端代码(188.40.77.206is eth0. 188.40.77.236是同一个服务器,但是 is eth0:1):

>>> import socket
>>> s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
>>> s.sendto('ping', 0, ("188.40.77.206", 24440))
4
>>> s.recvfrom(1024)
('Pong', ('188.40.77.206', 24440))
>>> s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
>>> s.sendto('ping', 0, ("188.40.77.236", 24440))
4
>>> s.recvfrom(1024)
[never gets anything]

服务器在这两种情况下都会收到“ping”数据包(因此在这两种情况下都会发送“pong”数据包)。

奇怪的是,这在某些地方确实有效(即我会得到两个 IP 的响应)。例如,它适用于188.40.37.137(相同的网络/数据中心,不同的服务器),也适用于89.18.189.160(不同的数据中心)。在这些情况下,recvfrom响应确实具有eth0IP,而不是连接到的 IP。

这只是UDP的规则吗?这是Python UDPServer类的问题/限制吗?是我做错了什么吗?除了简单地连接到eth0IP(或侦听特定 IP 而不是0.0.0.0)之外,还有什么方法可以让我完成这项工作?

4

2 回答 2

3

我在 TFTP 服务器上遇到了这个问题。我的服务器有两个面向同一个网络的 IP 地址。由于 UDP 是无连接的,因此在这种情况下可能会出现 IP 地址未按预期设置的问题。我的顺序是:

  1. 客户端将初始数据包发送到特定 IP 地址的服务器
  2. 服务器从传入的数据包中读取客户端的源地址,并发送响应。
    1. 但是,在响应中,服务器的“源地址”是根据路由表设置的,并且它被设置为另一个IP 地址。
    2. 无法控制服务器的“源”IP 地址,因为操作系统没有告诉我们请求来自哪个 IP 地址。
  3. 客户端从“其他”IP 地址获得响应,并拒绝它。

我的解决方案是专门将 TFTP 服务器绑定到我想监听的 IP 地址,而不是绑定到所有接口。

我在(TFTP 服务器)的Linux 手册页中tftpd发现了一些可能相关的文本。这里是:

 Unfortunately, on multi-homed systems, it is impossible for tftpd to
 determine the address on which a packet was received. As a result, tftpd
 uses two different mechanisms to guess the best source address to use for
 replies. If the socket that inetd(8) passed to tftpd is bound to a par‐
 ticular address, tftpd uses that address for replies. Otherwise, tftpd
 uses ‘‘UDP connect’’ to let the kernel choose the reply address based on
 the destination of the replies and the routing tables. This means that
 most setups will work transparently, while in cases where the reply
 address must be fixed, the virtual hosting feature of inetd(8) can be
 used to ensure that replies go out from the correct address.  These con‐
 siderations are important, because most tftp clients will reject reply
 packets that appear to come from an unexpected address.

请参阅此答案,它表明在 Linux可以读取传入 UDP 数据包的本地地址,并将其设置为传出数据包。在 C 中是可能的;不过,我不确定 Python。

于 2009-08-21T00:31:17.777 回答
1

这只是UDP的规则吗?

不。

这是 Python UDPServer 类的问题/限制吗?

疑。

是我做错了什么吗?

你的程序看起来是正确的。

数据报没有到达服务器的原因有很多。UDP 是无连接的,因此您的客户端只需将 ping 发送到以太网,而不知道是否有人收到它。

查看是否允许您绑定到该地址。有一个很棒的小程序叫做 netcat,它非常适合低级别的网络访问。它并不总是在每个系统上都可用,但它很容易下载和编译。

nc -l -s 188.40.77.236 -p 24440 -u

如果您像以前一样运行客户端程序,您应该会在终端上看到“Ping”。(您可以键入 Pong 并将其设置回您的客户端。玩起来很有趣。)如果您得到 ping,则不是网络问题,而是 Python 服务器程序或库有问题。如果 ping 不通,则无法建立连接。“请联系您的网络管理员寻求帮助。”

要检查的内容包括...

  1. 防火墙问题?
  2. 别名网络接口的配置问题。
  3. 用户权限问题。
于 2009-08-21T00:33:44.813 回答