4

我在这个站点上稍微修改了一个 server-client Twisted 程序,它提供了一个可以充当服务器和客户端的程序(How to write a twisted server that is also a client?)。我能够将服务器客户端连接到一侧的外部客户端和另一侧的外部服务器。我想通过服务器-客户端程序将数据从外部客户端传输到外部服务器。我遇到的问题是将 ServerProtocol 类(在服务器-客户端程序中)中接收到的行放入 ClientProtocol 类(在服务器-客户端程序中)。我尝试了多种方法,包括尝试使用工厂引用,正如您从 def init中看到的那样但我无法让它工作。(目前我只是将文字来回发送到外部服务器和客户端)这是服务器-客户端代码:

    from twisted.internet import protocol, reactor
    from twisted.protocols import basic


    class ServerProtocol(basic.LineReceiver):        
        def lineReceived(self, line):
            print "line recveived on server-client",line
            self.sendLine("Back at you from server-client")
            factory = protocol.ClientFactory()
            factory.protocol = ClientProtocol
            reactor.connectTCP('localhost', 1234, factory)

    class ClientProtocol(basic.LineReceiver):
        def __init__(self, factory):
            self.factory = factory

        def connectionMade(self):
            self.sendLine("Hello from server-client!")
            #self.transport.loseConnection()
        
        def lineReceived(self, line):
            print "line recveived on server-client1.py",line
            #self.transport.loseConnection()
          
    def main():
        import sys
        from twisted.python import log

        log.startLogging(sys.stdout)
        factory = protocol.ServerFactory()
        factory.protocol = ServerProtocol
        reactor.listenTCP(4321, factory)
        reactor.run()

    if __name__ == '__main__':
        main()

我应该提到,我能够分别在端口 4321 和 1234 上使用外部服务器和外部客户端连接到服务器-客户端程序,它们只是回显。此外,我还没有展示我多次尝试使用 self.factory 参考。任何意见或建议将不胜感激。

4

1 回答 1

5

这个问题与 Twisted FAQ 中的一个流行问题非常相似:

如何使一个连接上的输入导致另一个连接上的输出?

与您关于一个传入客户端连接和一个传出客户端连接的问题相反,FAQ 项目谈论到一台服务器的许多客户端连接没有任何显着差异。您在不同连接之间共享数据的方式是相同的。

该 FAQ 项目的基本要点是,基本上您想做的任何事情都涉及某种方法调用,并且 Twisted 中的方法调用与任何其他 Python 程序中的方法调用相同。您所需要的只是引用正确的对象来调用该方法。因此,例如,调整您的代码:

from twisted.internet import protocol, reactor
from twisted.protocols import basic

class ServerProtocol(basic.LineReceiver):        
    def lineReceived(self, line):
        self._received = line
        factory = protocol.ClientFactory()
        factory.protocol = ClientProtocol
        factory.originator = self
        reactor.connectTCP('localhost', 1234, factory)

    def forwardLine(self, recipient):
        recipient.sendLine(self._received)

class ClientProtocol(basic.LineReceiver):
    def connectionMade(self):
        self.factory.originator.forwardLine(self)
        self.transport.loseConnection()

def main():
    import sys
    from twisted.python import log

    log.startLogging(sys.stdout)
    factory = protocol.ServerFactory()
    factory.protocol = ServerProtocol
    reactor.listenTCP(4321, factory)
    reactor.run()

if __name__ == '__main__':
    main()

注意如何:

  • 我摆脱__init__ClientProtocol. ClientFactory不带参数调用它的协议。需要参数的 An__init__将导致TypeError引发 a。此外,ClientFactory已经将自己设置为它创建的协议的工厂属性。
  • 我通过将实例设置为客户端工厂的属性ClientProtocol来引用该实例。由于实例具有对实例的引用,这意味着它具有对实例的引用。ServerProtocolServerProtocoloriginatorClientProtocolClientFactoryServerProtocol
  • 一旦建立连接,我添加了可用于指导执行任何应用程序逻辑的forwardLine方法。请注意,由于上一点,调用此方法没有问题。ClientProtocolServerProtocolClientProtocolClientProtocol
于 2012-05-30T11:59:23.510 回答