4

このサイトのサーバークライアントツイストプログラムを少し変更しました。これは、サーバーおよびクライアントとして機能できるプログラムを提供します(クライアントでもあるツイストサーバーの作成方法は?)。サーバークライアントを一方の外部クライアントに接続し、もう一方の外部サーバーに接続することができます。サーバークライアントプログラムを介して外部クライアントから外部サーバーにデータを転送したい。私が抱えている問題は、ServerProtocolクラス(server-clientプログラム内)で受信した行をClientProtocolクラス(server-clientプログラム内)に取り込むことです。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

この質問は、TwistedFAQの人気のある質問と非常によく似ています。

ある接続で入力して別の接続で出力する方法を教えてください。

1つの着信クライアント接続と1つの発信クライアント接続に関する質問とは対照的に、FAQ項目が1つのサーバーへの多数のクライアント接続について話していることには大きな違いはありません。異なる接続間でデータを共有する方法は同じです。

その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__のメソッドを削除しましたClientProtocolClientFactory引数なしでプロトコルを呼び出します。__init__引数が必要な場合は、発生しますTypeError。さらに、ClientFactory作成するプロトコルのファクトリ属性としてすでに設定されています。
  • インスタンスをクライアントファクトリの属性として設定することによりClientProtocol、インスタンスへの参照を提供しました。インスタンスにはインスタンスへの参照があるため、インスタンスへの参照があることを意味します。ServerProtocolServerProtocoloriginatorClientProtocolClientFactoryServerProtocol
  • 接続が確立されたら、アプリケーションロジックが何であれ実行するように指示するために使用できるforwardLineメソッドを追加しました。前のポイントのため、このメソッドの呼び出しに問題がないことに注意してください。ClientProtocolServerProtocolClientProtocolClientProtocol
于 2012-05-30T11:59:23.510 に答える