我的计算机可能位于多个防火墙后面,只有一个私有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()
行self.request[1].send("test")
失败并显示错误:[Errno 89] Destination address required
,我读的越多,我就越不能将数据发送回客户端,至少不会使用这个简单的“send
”解决方案。
我无法更改客户端。是否有任何方法可以重用套接字来发送UDP数据?也许那里有一个我不知道的“救世主”课程?任何暗示都将受到赞赏。
提前谢谢你。
答案 0 :(得分:5)
您必须使用.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
答案 1 :(得分:1)
虽然从客户端和服务器的角度来看,UDP是无连接的,但从NAT /路由器的角度来看,有一个为双向通信而维护的连接。服务器只需要回复它收到消息的IP /端口即可到达客户端。
python doc就是一个很好的例子:http://docs.python.org/2/library/socketserver.html#socketserver-udpserver-example
基本上它只需要请求地址并使用sendto函数
socket.sendto("test", self.client_address)