Pyzor使用UDP / IP作为通信协议。我们最近将公共服务器切换到新机器,并开始收到许多超时的报告。我发现如果我将从eth0:1
查询的IP更改为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.206
是eth0
。188.40.77.236
是同一台服务器,但是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
响应确实具有eth0
IP,而不是连接到的IP。
这只是UDP的规则吗?这是Python UDPServer
类的问题/限制吗?这是我做错了吗?除了简单地连接到eth0
IP(或者监听特定的IP而不是0.0.0.0
)之外,我有什么方法可以完成这项工作吗?
答案 0 :(得分:3)
我遇到了TFTP服务器。我的服务器有两个面向同一网络的IP地址。由于UDP是无连接的,因此在这种情况下可能会出现未按预期设置IP地址的问题。我的顺序是:
我的解决方案是将TFTP服务器专门绑定到我想要侦听的IP地址,而不是绑定到所有接口。
我发现了一些可能与Linux man page for tftpd
(TFTP服务器)相关的文本。这是:
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.
请参阅this answer,其中显示在Linux上 可以读取传入UDP数据包的本地地址,并将其设置为传出数据包。它可能在C;我不确定Python。
答案 1 :(得分:1)
这只是UDP的规则吗?
没有
这是一个问题/限制 Python UDPServer类?
疑。
这是我做错了吗?
您的程序看起来不错。
数据报没有到达服务器的原因有很多。 UDP是无连接的,因此您的客户端只需将ping发送到以太网而不知道是否有人收到它。
查看是否允许绑定到该地址。有一个很棒的小程序叫做netcat,非常适合低级网络访问。它并不总是在每个系统上都可用,但它很容易下载和编译。
nc -l -s 188.40.77.236 -p 24440 -u
如果您像以前一样运行客户端程序,则应在终端上看到“Ping”。 (你可以输入Pong并将它设置回你的客户端。玩起来很有趣。)如果你得到ping,网络问题不是问题,而且Python服务器程序或库有问题。如果没有ping,则无法建立连接。 “请联系您的网络管理员以获取帮助。”
要检查的内容包括......