Skip to main content
 首页 » 编程设计

python之UDP Socketserver之通过同一个套接字发送数据(不可能)

2025年05月04日18me-sa

我有一台可能位于多个防火墙后面的计算机,只有一个私有(private) IP... 几乎无法从外界访问。

该计算机定期将 UDP 数据发送到远程服务器(可从任何地方访问)。该远程服务器可能与 UDP 发送方/客户端位于不同的网络中(或者位于不同的国家/地区)。

在某个时候,我必须发送一个包,确认我收到了一些数据返回到“无法访问”的计算机,这意味着:客户端开始通信并且我有一个套接字。

我害怕回答,因为我读到的 UDP 协议(protocol)主要是发送-->断开连接-->忘记包,但问题来了。有什么方法可以使用现有的 UDP 套接字发送数据吗?

作为服务器,我使用一个非常简单的 SocketServer 类:

class MyUDPHandler(SocketServer.BaseRequestHandler): 
 
    def handle(self): 
        message_type = message_utils.extract_type(self.request[0]) 
        message_cls = message_factory.get_class_by_message_type(message_type) 
        message = message_cls( 
                              data=self.request[0], 
                              came_from=self.client_address) 
        print "Got %s" % message 
        message.process() 
        self.request[1].send("test")  
 
if __name__ == "__main__": 
    SERVER_HOST = settings.SERVER_HOST\ 
                        if hasattr(settings, "SERVER_HOST") else "" 
    SERVER_PORT = int(settings.SERVER_PORT) 
    server = SocketServer.UDPServer( 
                                    (SERVER_HOST, SERVER_PORT), 
                                    MyUDPHandler) 
    server.serve_forever() 

self.request[1].send("test") 行失败并出现错误:[Errno 89] Destination address required 以及我阅读的更多内容关于它,我越想我将无法将数据发送回客户端,至少不能使用这个简单的“send”解决方案。

我无法更改客户端。有什么方法可以重用套接字发送 UDP 数据吗?也许那里有一个我不知道的“救世主”类(class)?任何提示将不胜感激。

提前致谢。

请您参考如下方法:

你必须使用.sendto(),而不是.send(),像这样:

self.request[1].sendto( 
  "test", 
  self.client_address)  

引用:http://docs.python.org/2/library/socketserver.html#socketserver-udpserver-example


额外内容:

比我能创建的最小的响应式 UDP 套接字服务器:

import SocketServer 
class MyUDPHandler(SocketServer.BaseRequestHandler): 
    def handle(self): 
        self.request[1].sendto( "test\n", self.client_address) 
SocketServer.UDPServer( ("", 5432), MyUDPHandler).serve_forever() 

因此可以从 Linux 命令行进行测试:

$ nc -u 127.1 5432