Python UDP 数据包从未到达
最近几天,我一直在研究如何通过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来测试你的代码。
谢谢。