Python UDP 数据包从未到达

3 投票
1 回答
1552 浏览
提问于 2025-04-17 21:21

最近几天,我一直在研究如何通过UDP发送数据(我打算做一个简单的多人游戏)。到目前为止,一切都很好,直到我发现它在局域网(LAN)上工作得很好,但在互联网上根本收不到数据包。我在一台电脑上运行测试服务器和测试脚本(代码在下面),通过局域网发送数据时,一切正常(但是在互联网上发送时,Wireshark会显示“端口不可达”的错误)。当我在不同的电脑上运行客户端和服务器时,我可以在互联网上和局域网中发送数据,但目的地根本收不到任何东西。我花了几个小时在网上查资料,确保端口已经转发,调整了设置,仔细检查了代码,使用Wireshark进行监测,还和其他人一起测试,结果还是没用。

我到底哪里出错了?

这是我的测试代码:

import socket, pickle
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sock.setblocking(0)
port = 5000

type = raw_input("1=Server 2=Client 3=Local Client: ")

if type == "1":
  ip = ""
  sock.bind((ip,port))
  print("Socket: "+str(sock.getsockname()))
  while True:
    try:
      rdata, addr = sock.recvfrom(1024)
      data = pickle.loads(rdata)
      print addr, ">>>", data
    except:
      pass

elif type == "2":
  ip = "79.222.132.25"
  sock.bind(("192.168.2.102",port+1))
  sock.connect((ip,port))
  print("Socket: "+str(sock.getsockname()))
  print("Connected to: "+str(sock.getpeername()))
  while True:
    input = raw_input("Send:")
    data = pickle.dumps((input))
    sock.send(data)

else:
  ip = "192.168.2.102"
  sock.bind((ip,port+1))
  while True:
    input = raw_input("Send:")
    data = pickle.dumps((input))
    sock.sendto(data,(ip,port))

提前感谢大家的帮助。

1 个回答

3

我刚刚在网上运行了你的代码,结果很好。我用类型1和类型2进行了测试。

首先,我建议你去掉客户端中的绑定端口那一行。像这样:

elif type == "2":
ip = "79.222.132.25"
# sock.bind(("192.168.2.102",port+1))
sock.connect((ip,port))
print("Socket: "+str(sock.getsockname()))
print("Connected to: "+str(sock.getpeername()))
while True:
    input = raw_input("Send:")
    data = pickle.dumps((input))
    sock.send(data)

因为通常情况下,客户端不需要明确绑定端口——当你调用sock.connect()时,系统会自动为你的套接字分配一个随机端口。

接下来我们来解决你的问题。你的代码是正确的,所以问题可能出在网络上,更可能是服务器的问题。

如果你的服务器在一个NAT网关或路由器后面,任何进入的连接都会被你的网关拒绝。测试服务器状态的一个简单方法是,在命令行中输入ipconfig(在Linux中是ifconfig),查看本地IP地址是否是公共互联网地址。你可以通过这个网站获取公共互联网地址:whatismyipaddress.com

这可能是你遇到的最常见的问题。解决服务器网络环境的一个简单方法是找一个有静态公共IP的真实服务器,并且没有任何NAT网关。或者你可以租一个VPS来测试你的代码。

谢谢。

撰写回答