UDP Socketserver-通过同一套接字发送数据(不可能吗?)

Bor*_*jaX 1 python sockets udp request

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

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

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

我很害怕答案,因为我读到的UDP协议主要是发送->断开连接->忘记软件包,但这是问题所在。是否可以使用现有的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()
Run Code Online (Sandbox Code Playgroud)

该行self.request[1].send("test")失败并显示错误:[Errno 89] Destination address required我了解得越多,我就越无法将数据发送回客户端,至少不是通过这种简单的send解决方案。

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

先感谢您。

Rob*_*obᵩ 5

您必须这样使用.sendto(),而不是.send()

self.request[1].sendto(
  "test",
  self.client_address) 
Run Code Online (Sandbox Code Playgroud)

参考: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()
Run Code Online (Sandbox Code Playgroud)

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

$ nc -u 127.1 5432
Run Code Online (Sandbox Code Playgroud)