UDP服务是否必须从连接的IP地址进行响应?

2024-10-01 07:36:31 发布

您现在位置:Python中文网/ 问答频道 /正文

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.206eth0188.40.77.236是同一个服务器,但是是eth0:1):

^{pr2}$

服务器在这两种情况下都获得“ping”包(因此在这两种情况下都发送“pong”包)。在

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

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


Tags: 代码selfip服务器机器报告情况数据中心
2条回答

Is this just a rule of UDP?

没有

Is this a problem/limitation with the Python UDPServer class?

怀疑。在

Is it something I'm doing incorrectly?

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

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

看看你是否被允许绑定到那个地址。有一个很棒的小程序叫做netcat,它非常适合于低层的网络访问。并非每个系统都可以使用它,但它很容易下载和编译。在

nc -l -s 188.40.77.236 -p 24440 -u

如果您像以前一样运行客户机程序,您应该会看到“Ping”打印在您的终端上。(您可以键入Pong并将其设置回客户端。如果你得到了ping,网络问题就不是问题所在,Python服务器程序或库出了问题。如果你没有收到ping,就无法建立连接。”请与网络管理员联系以获取帮助。“

检查的内容包括。。。在

  1. 防火墙问题?在
  2. 别名网络接口的配置问题。在
  3. 用户权限问题。在

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

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

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

我发现了一些可能与Linux man page for ^{}(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。在

相关问题 更多 >