【问题标题】:how to recive data whitout port forwarding using udp如何使用 udp 在没有端口转发的情况下接收数据
【发布时间】:2014-10-14 10:17:36
【问题描述】:

首先,我在套接字编程方面完全是个菜鸟,所以请告诉我你是否认为我做错了什么。

所以,我一直在尝试为一个简单的 fps 游戏编写一个 udp 服务器。

在本地网络上一切正常,但是如果我尝试在 Internet 上使用我的代码,我确实会遇到一些问题。我的服务器可以接收来自客户端白化问题的数据,并且可以向客户端发送数据,如果它发送的端口在客户端上是打开的,如果不是,客户端将不会接收任何数据。 (服务器上的端口全部打开)。我现在的问题是,有没有什么方法可以在不需要打开/转发端口的情况下通过 Internet 接收数据?

(client()函数不断循环重复)

我的接收数据代码如下:

import socket

server_IP = 'ip of server'
Client_port = 3560
Server_port = 5000
Client_socket = None
First_run = True
first = True

def client():
    global server_IP
    global Client_port
    global Server_port
    global Client_socket
    global first
    if first == True:
        try:
            local = ('', Client_port)
            host = (server_IP, Server_port)
            Client_socket  = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            Client_socket.bind(local)
            Client_socket.setblocking(False)
            first = False
        except:
            print("Failed")
    try:
        data, connection = Client_socket.recvfrom(512)
    except socket.error:
        return
    if data:
        #irrelevant code handling the data...

服务器发送代码是这样锁定的:

import socket
server_socket = None
server_port = 5000
Data_Port = 3560
print("importing the socket...")
try:
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
except socket.error as msg:
    server_socket = None
try:
    server_socket.bind(("", server_port))
except socket.error as msg:
    server_socket.close()
    server_socket = None
if server_socket is None:
    print('could not open socket')
    ret = False
server_socket.sendto(Data_to_Send, ('client ip here',Data_Port))

ofc 这只是代码的一部分,但我想它是相关的。 如果在我发送/接收数据的方式中不需要打开/转发端口就无法接收数据,请建议一种可以做到这一点的方法,如果有的话。

【问题讨论】:

    标签: python sockets python-3.x port


    【解决方案1】:

    看看UDP打孔:

    http://en.wikipedia.org/wiki/UDP_hole_punching

    基本前提是客户端首先连接到您的服务器,在 NAT 路由表中创建一个条目。然后服务器查看请求以查看 NAT 路由器用于发送请求的端口。您应该能够向此端口发送 UDP 数据包,然后将其转发到专用网络中的客户端。

    总之,不要将您的端口硬编码为3560。您需要根据 UDP 数据包的来源更改此端口。

    您可能还想考虑使用基于连接的协议 TCP(UDP 是无连接的)- 当从客户端建立到服务器的连接时,通过此连接来回发送数据非常容易。

    【讨论】:

    • 好的,这让我有了更多的理解,但是我不明白客户端是如何知道它应该绑定到哪个端口的(或者它可能不需要绑定?)。我正在使用socket.sendto方法向服务器发送数据,这个方法是使用随机的吗?每次端口,我都可以轻松地让服务器响应这个随机端口(在接收数据时在同一个端口上响应),但是我怎样才能让客户端在这个端口上寻找答案呢?因为它是随机的我需要在每次通话时重新绑定它吗?我如何在客户端获取上次 sendto 调用使用的端口?
    【解决方案2】:

    由于这个问题很难找到一个明确的答案,而且当我开始工作时,这要感谢 Martin Konecny 关于打孔的解释(例如。 http://en.wikipedia.org/wiki/UDP_hole_punching),但也要感谢我自己的许多“试错”尝试。

    我在哪里做错了最有可能的事实是我关闭了客户端上用于进行 sendto 调用的套接字,然后尝试在新套接字上侦听来自服务器的答案。这不起作用,或者至少我没有让它起作用。但是,如果我没有关闭套接字,并在我用来进行 sendto 调用的同一个套接字上听取了答案,那么一切正常。事实证明,我什至不需要像我在问题中所做的那样绑定套接字即可。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-01
      • 2022-11-22
      • 2018-03-05
      • 2021-08-19
      • 1970-01-01
      • 2017-12-24
      • 2018-05-08
      • 1970-01-01
      相关资源
      最近更新 更多