过去几天我花了很多时间试图弄清楚如何通过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))
提前感谢您的帮助。
答案 0 :(得分: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()时,系统会自动为你的套接字分配一个随机端口。
然后让我们解决你的问题。 您的代码是正确的,因此Internet必定存在问题,更可能是服务器。 如果您的服务器在NAT网关或路由器下工作,则您的网关将拒绝任何传入连接。测试服务器状态的简便方法是在命令行提示符下键入ipconfig(或Linux中的ifconfig),以检查本地IP地址是否为公共Internet地址。公共互联网地址可以从这个网站检索:whatismyipaddress.com。
这是您可能遇到的最大问题。 使服务器网络环境正确的最简单方法是找到一个真正的服务器,它具有静态公共IP,并且没有任何NAT网关。或者只是租一个VPS来测试你的代码。
感谢。