sockets - 游戏客户端如何从服务器接收 UDP 数据?
问题描述
我想做的事:
为了学习游戏编程,我使用专用服务器和 UDP 创建了一个回声设置。专用服务器位于不同的城市(又名不在我的本地网络中)。
在我的本地计算机上,我有一个 udp 客户端和服务器(2 个不同的程序)。当我第一次启动我的 python 服务器时,windows 防火墙立即询问我是否要添加异常。在允许我的 python 服务器联网后,我仍然没有收到任何消息。(客户端 -> 专用服务器 -/-> 本地服务器)
只有在我的路由器中设置了端口转发后,我才能在我的本地 UDP 服务器上接收消息。
我的问题是:
游戏如何解决这个问题?我没有为每个我想玩的多人游戏激活端口转发,我仍然能够在所有这些游戏中接收数据。
我的专用服务器设置(地址和端口故意更改):
#!/usr/bin/python3
import socket
ADDRESS = "1.123.123.123"
PORT = 12345
serverSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
serverSock.bind((ADDRESS, PORT))
clientSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
addresses = []
while True:
data, addr = serverSock.recvfrom(1024)
if addr not in addresses:
addresses.append(addr)
msg = str(data)
#if msg.split()
print("Message: " + str(data))
outMsg = str(addr) + ":" + msg
for ad in addresses:
print("Send Msg " + outMsg + " to " + ad[0] + ":" + str(PORT))
clientSock.sendto(bytes(outMsg, "utf-8"), (ad[0], 12345))
print("Addresses: " + str(addresses))
解决方案
我在写这个问题时想出了这个问题(就像和老橡皮鸭说话一样):
诀窍是不在本地计算机上使用 2 个程序。发送消息的程序也需要检索消息。在我的示例中,它是阻塞调用(丑陋!),对于您想要使其异步的游戏。但这是绕过路由器防火墙的最简单方法:
#! /usr/bin/python3
import socket
ADDRESS = "1.123.123.123"
PORT = 12345
clientSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# usually not required to bind a client, but we want to receive messages
clientSock.bind(("0.0.0.0",PORT))
while True:
msg = input("Enter message: ")
# Note that it is not required to send to the same port
# you have locally binded to.
clientSock.sendto(bytes(msg, "utf-8"), (ADDRESS, PORT))
# listen to the echo:
data, addr = clientSock.recvfrom(1024)
print(str(data) + " from " + str(addr))
但是,我对套接字和防火墙的理解是有限的。我不明白为什么这行得通,但 2 个单独的程序却不行。也许有人可以对此发表评论。希望我可以节省一些时间=)