【问题标题】:Twisted Python: UDP Broadcast (simple echo server)Twisted Python:UDP 广播(简单的回显服务器)
【发布时间】:2014-02-14 03:19:03
【问题描述】:

我正在尝试调整 Python Twisted - UDP examples 以使用 UDP 广播。我可以从客户端发送一条消息并在服务器上接收它,但是它不会发回消息。

客户:

from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor

from socket import SOL_SOCKET, SO_BROADCAST

class EchoClientDatagramProtocol(DatagramProtocol):
    strings = [
        "Hello, world!",
        "What a fine day it is.",
        "Bye-bye!"
    ]

    def startProtocol(self):
        self.transport.socket.setsockopt(SOL_SOCKET, SO_BROADCAST, True)
        self.transport.connect("255.255.255.255", 8000)
        self.sendDatagram()

    def sendDatagram(self):
        if len(self.strings):
            datagram = self.strings.pop(0)
            self.transport.write(datagram)
        else:
            reactor.stop()

    def datagramReceived(self, datagram, host):
        print 'Datagram received: ', repr(datagram)
        self.sendDatagram()

def main():
    protocol = EchoClientDatagramProtocol()
    #0 means any port
    t = reactor.listenUDP(0, protocol)
    reactor.run()

if __name__ == '__main__':
   main()

服务器:

from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor

class EchoUDP(DatagramProtocol):
    def datagramReceived(self, datagram, address):
        print "Received from address: " + str(address)
        print str(datagram)
        self.transport.write(datagram, address)
        print "Finished sending reply."

print "Starting server."
reactor.listenUDP(8000, EchoUDP())
reactor.run()

控制台输出:

Server:

Starting server.
Received from address ('192.168.1.137', 53737)
Hello, world!
Finished sending reply.

Client:

no output.

【问题讨论】:

  • 您的意思是mainEchoClientDatagramProtocol 中的一个函数,还是格式问题?
  • @jozzas:格式问题,我很抱歉。我已经编辑了上面的代码。

标签: python twisted


【解决方案1】:

transport.connect 创建一个connected UDP socket

已连接的 UDP 套接字与标准套接字略有不同 - 它只能向/从单个地址发送和接收数据报,但这绝不意味着连接。数据报仍可能以任何顺序到达,而另一端的端口可能没有人在监听。连接的 UDP 套接字的好处是它可以提供未交付包的通知。这取决于许多因素,几乎所有这些因素都超出了应用程序的控制范围,但它仍然具有某些偶尔会使其有用的好处。

我怀疑来自服务器的响应没有被客户端捕获,因为它正在侦听来自广播地址的响应,而不是服务器的特定地址。

相反,只需使用self.transport.write(data, (host, port)) 形式的写入而不首先启动连接 - 这将允许客户端接收来自任何地址的数据包。

from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor

from socket import SOL_SOCKET, SO_BROADCAST

class EchoClientDatagramProtocol(DatagramProtocol):
    strings = [
        "Hello, world!",
        "What a fine day it is.",
        "Bye-bye!"
    ]

    def startProtocol(self):
        self.transport.socket.setsockopt(SOL_SOCKET, SO_BROADCAST, True)
        #self.transport.connect("255.255.255.255", 8000) <- not needed
        self.sendDatagram()

    def sendDatagram(self):
        if len(self.strings):
            datagram = self.strings.pop(0)
            self.transport.write(datagram, ('255.255.255.255', 8000)) # <- write to broadcast address here
        else:
            reactor.stop()

    def datagramReceived(self, datagram, host):
        print 'Datagram received: ', repr(datagram)
        self.sendDatagram()

def main():
    protocol = EchoClientDatagramProtocol()
    #0 means any port
    t = reactor.listenUDP(0, protocol)
    reactor.run()


if __name__ == '__main__':
   main()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 2013-06-15
    • 2013-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-31
    相关资源
    最近更新 更多