【问题标题】:UDP Socketserver - send data through same socket (impossible?)UDP Socketserver - 通过同一个套接字发送数据(不可能?)
【发布时间】:2013-04-18 15:50:41
【问题描述】:

我的计算机可能位于多个防火墙之后,只有一个私有 IP……几乎无法从外部世界访问。

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

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

我害怕答案,因为我读到的 UDP 协议主要是 send-->disconnect-->忘记包,但问题来了。有没有办法使用现有的 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 数据?也许那里有一个我不知道的“救世主”课程?任何提示将不胜感激。

提前谢谢你。

【问题讨论】:

  • 我猜这个问题与 UDP 是一个无连接协议有关。我不确定包装类会改变这一点。
  • 是的...这正是我的意思我害怕答案 :(我想我希望得到一些魔法。感谢您阅读这个问题!

标签: python sockets udp request


【解决方案1】:

你必须使用.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

【讨论】:

    【解决方案2】:

    虽然从客户端和服务器的角度来看,UDP 是无连接的,但从 NAT/路由器的角度来看,存在一个为双向通信而维护的连接。服务器只需要回复它收到消息的 IP/端口即可到达客户端。

    python 文档有一个很好的例子:http://docs.python.org/2/library/socketserver.html#socketserver-udpserver-example

    基本上只需要请求地址并使用sendto函数

    socket.sendto("test", self.client_address)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-23
      • 1970-01-01
      • 2011-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多