首页 > 解决方案 > 游戏客户端如何从服务器接收 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))

标签: socketsnetworkingudpgame-engineportforwarding

解决方案


我在写这个问题时想出了这个问题(就像和老橡皮鸭说话一样):

诀窍是不在本地计算机上使用 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 个单独的程序却不行。也许有人可以对此发表评论。希望我可以节省一些时间=)


推荐阅读