扭曲的服务器-客户端数据共享 [英] Twisted server-client data sharing

查看:34
本文介绍了扭曲的服务器-客户端数据共享的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我稍微修改了这个站点上的一个服务器-客户端 Twisted 程序,它提供了一个可以充当服务器和客户端的程序(如何编写一个同时也是客户端的扭曲服务器?).我能够将服务器客户端连接到一侧的外部客户端和另一侧的外部服务器.我想通过服务器-客户端程序将数据从外部客户端传输到外部服务器.我遇到的问题是将 ServerProtocol 类(在服务器-客户端程序中)中接收到的行放入 ClientProtocol 类(在服务器-客户端程序中).我已经尝试了多种方法来做到这一点,包括尝试使用工厂参考,正如您从 def init 看到的那样,但我无法让它工作.(目前我只是向外部服务器和客户端来回发送文字)这是服务器 - 客户端代码:

 来自twisted.internet 导入协议,反应器从twisted.protocols 导入基本类 ServerProtocol(basic.LineReceiver):def lineReceived(self, line):打印服务器-客户端接收到的行",行self.sendLine(从服务器客户端回到你")工厂 = 协议.ClientFactory()factory.protocol = ClientProtocolreactor.connectTCP('localhost', 1234, factory)类 ClientProtocol(basic.LineReceiver):def __init__(self, factory):self.factory = 工厂def connectionMade(self):self.sendLine(来自服务器客户端的你好!")#self.transport.loseConnection()def lineReceived(self, line):打印在 server-client1.py 上收到的行",行#self.transport.loseConnection()定义主():导入系统从twisted.python 导入日志log.startLogging(sys.stdout)工厂 = 协议.ServerFactory()factory.protocol = 服务器协议reactor.listenTCP(4321,工厂)反应器运行()如果 __name__ == '__main__':主要的()

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

解决方案

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

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

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

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

来自twisted.internet 导入协议,反应器从twisted.protocols 导入基本类 ServerProtocol(basic.LineReceiver):def lineReceived(self, line):self._received = 行工厂 = 协议.ClientFactory()factory.protocol = ClientProtocolfactory.originator = 自己reactor.connectTCP('localhost', 1234, factory)def forwardLine(自己,收件人):收件人.sendLine(self._received)类 ClientProtocol(basic.LineReceiver):def connectionMade(self):self.factory.originator.forwardLine(self)self.transport.loseConnection()定义主():导入系统从twisted.python 导入日志log.startLogging(sys.stdout)工厂 = 协议.ServerFactory()factory.protocol = 服务器协议reactor.listenTCP(4321,工厂)反应器运行()如果 __name__ == '__main__':主要的()

注意方法:

  • 我去掉了 ClientProtocol 上的 __init__ 方法.ClientFactory 不带参数调用它的协议.需要参数的 __init__ 将导致引发 TypeError.此外,ClientFactory 已经将自己设置为它创建的协议的工厂属性.
  • 我通过将 ServerProtocol 实例设置为 originator 属性,为 ClientProtocol 提供了对 ServerProtocol 实例的引用客户工厂.由于 ClientProtocol 实例引用了 ClientFactory 实例,这意味着它引用了 ServerProtocol 实例.
  • 我添加了 forwardLine 方法,一旦 ClientProtocol 连接建立.请注意,由于上一点,ClientProtocol 调用此方法没有问题.

I slightly modified a server-client Twisted program on this site, which provided a program that could act as a server and a client (How to write a twisted server that is also a client?). I am able to connect the server-client to an external client on one side and an external server on the other. I want to transfer data from the external client to the external server via the server-client program. The problem I am having is getting the line received in the ServerProtocol class (in the server-client program) into the ClientProtocol class (in the server-client program). I have tried a number of ways of doing this, including trying to use the factory reference, as you can see from the def init but I cannot get it to work. (at the moment I am just sending literals back and forth to the external server and client) Here is the server-client code:

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

I should mention that I am able to connect to the server-client program with the external server and external client on ports 4321 and 1234 respectively and they just echo back. Also, I have not shown my many attempts to use the self.factory reference. Any advice or suggestions will be much appreciated.

解决方案

This question is very similar to a popular one from the Twisted FAQ:

How do I make input on one connection result in output on another?

It doesn't make any significant difference that the FAQ item is talking about many client connections to one server, as opposed to your question about one incoming client connection and one outgoing client connection. The way you share data between different connections is the same.

The essential take-away from that FAQ item is that basically anything you want to do involves a method call of some sort, and method calls in Twisted are the same as method calls in any other Python program. All you need is to have a reference to the right object to call the method on. So, for example, adapting your code:

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

Notice how:

  • I got rid of the __init__ method on ClientProtocol. ClientFactory calls its protocol with no arguments. An __init__ that requires an argument will result in a TypeError being raised. Additionally, ClientFactory already sets itself as the factory attribute of protocols it creates.
  • I gave ClientProtocol a reference to the ServerProtocol instance by setting the ServerProtocol instance as the originator attribute on the client factory. Since the ClientProtocol instance has a reference to the ClientFactory instance, that means it has a reference to the ServerProtocol instance.
  • I added the forwardLine method which ClientProtocol can use to direct ServerProtocol to do whatever your application logic is, once the ClientProtocol connection is established. Notice that because of the previous point, ClientProtocol has no problem calling this method.

这篇关于扭曲的服务器-客户端数据共享的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆