简体   繁体   English

扭曲的UDP到TCP桥

[英]Twisted UDP to TCP Bridge

Recently I've taken my first stab at Twisted/Python building an app that echoes incoming UDP strings out the TCP port. 最近,我第一次尝试使用Twisted / Python构建一个应用程序,它将传入的UDP字符串从TCP端口回送出去。 I assumed this would be very simple, but I haven't been able to get it to work. 我认为这很简单,但我无法让它工作。 The code below is the example TCP & UDP Server modified to run together. 下面的代码是修改为一起运行的示例TCP和UDP服务器。 I'm just trying to pass some data between the two. 我只是想在两者之间传递一些数据。 Any help would be appreciated. 任何帮助,将不胜感激。

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()

This is essentially the frequently asked How do I make input on one connection result in output on another? 这基本上是经常被问到如何在一个连接上输入结果导致另一个连接上的输出?

The UDP<->TCP specifics in this question don't break the general answer given in the FAQ entry. 此问题中的UDP < - > TCP细节不会破坏FAQ条目中给出的一般答案。 Just notice that a DatagramProtocol is easier to work with than a Protocol because you already have the DatagramProtocol instance without having to get the cooperation of a factory as you do in the Protocol case. 请注意, DatagramProtocolProtocol更容易使用,因为您已经拥有DatagramProtocol实例,而无需像在Protocol案例中那样获得工厂的合作。

Put another way: 换一种方式:

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()

Notice the essential change: UDPServer needs to call a method on an instance of TCPServer so it needs a reference to that instance. 注意基本的变化: UDPServer需要在TCPServer一个实例上调用一个方法,因此它需要对该实例的引用。 This is achieved by making the TCPServer instance pass itself to the UDPServer initializer and making the UDPServer initializer save that reference as an attribute of the UDPServer instance. 这是通过使TCPServer实例将自身传递给UDPServer初始化程序并使UDPServer初始化程序将该引用保存为UDPServer实例的属性来实现的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM