【问题标题】:Twisted UDP to TCP Bridge扭曲的 UDP 到 TCP 桥接器
【发布时间】:2013-11-29 06:30:41
【问题描述】:

最近,我第一次尝试使用 Twisted/Python 构建一个应用程序,该应用程序将传入的 UDP 字符串回显到 TCP 端口。我认为这将非常简单,但我无法让它工作。下面的代码是修改为一起运行的示例 TCP 和 UDP 服务器。我只是想在两者之间传递一些数据。任何帮助将不胜感激。

from twisted.internet.protocol import Protocol, Factory, DatagramProtocol
from twisted.internet import reactor

class TCPServer(Protocol):

    def dataReceived(self, data):
        self.transport.write(data)


class UDPServer(DatagramProtocol):

    def datagramReceived(self, datagram, address):
        #This is where I would like the TCPServer's dataReceived method run passing "datagram".  I've tried: 
        TCPServer.dataReceived(datagram)
        #But of course that is not the correct call because UDPServer doesn't recognize "dataReceived"


def main():
    f = Factory()
    f.protocol = TCPServer
    reactor.listenTCP(8000, f)
    reactor.listenUDP(8000, UDPServer())
    reactor.run()

if __name__ == '__main__':
    main()

【问题讨论】:

    标签: python tcp udp twisted tunnel


    【解决方案1】:

    这基本上就是经常被问到的How do I make input on one connection result in output on another?

    此问题中的 UDPTCP 细节不会破坏常见问题解答条目中给出的一般答案。请注意DatagramProtocolProtocol 更容易使用,因为您已经拥有DatagramProtocol 实例,而无需像在Protocol 案例中那样获得工厂的合作。

    换一种说法:

    from twisted.internet.protocol import Protocol, Factory, DatagramProtocol
    from twisted.internet import reactor
    
    class TCPServer(Protocol):
        def connectionMade(self):
            self.port = reactor.listenUDP(8000, UDPServer(self))
    
        def connectionLost(self, reason):
            self.port.stopListening()
    
    
    class UDPServer(DatagramProtocol):
        def __init__(self, stream):
            self.stream = stream
    
        def datagramReceived(self, datagram, address):
            self.stream.transport.write(datagram)
    
    
    def main():
        f = Factory()
        f.protocol = TCPServer
        reactor.listenTCP(8000, f)
        reactor.run()
    
    if __name__ == '__main__':
        main()
    

    请注意根本的变化:UDPServer 需要在 TCPServer 的实例上调用方法,因此它需要对该实例的引用。这是通过使TCPServer 实例将自身传递给UDPServer 初始化程序并使UDPServer 初始化程序将该引用保存为UDPServer 实例的属性来实现的。

    【讨论】:

    • 我以前看过那个例子,但据我了解,DatagramProtocol 不能/不使用工厂。当我尝试像您共享的示例一样解决此问题时,我遇到了 UDPServer 不喜欢被共享工厂引用的错误。换句话说,UDP 打破了“一个连接,另一个输出”的例子。
    猜你喜欢
    • 2015-12-30
    • 1970-01-01
    • 2013-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多