2012-05-29 104 views
4

我稍微修改了此站点上的服务器 - 客户端Twisted程序,该程序提供了可充当服务器和客户端的程序(http://stackoverflow.com/questions/3275004/how-到写一个捻 - 服务器 - 即此结果也-A-客户端)。我能够将服务器客户端连接到一端的外部客户端和另一端的外部服务器。我想通过服务器客户端程序将数据从外部客户端传输到外部服务器。我遇到的问题是将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参考。任何意见或建议将不胜感激。

回答

5

这个问题是非常相似流行的从扭曲的常见问题解答:

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

它不会使该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() 

注意如何:

  • 我上ClientProtocol摆脱__init__方法。 ClientFactory不带参数地调用它的协议。需要参数的__init__将导致TypeError被引发。此外,ClientFactory已将其自身设置为其创建的协议的工厂属性。
  • 我通过在客户端工厂将ServerProtocol实例设置为originator属性,给ClientProtocol实例引用了ServerProtocol实例。由于ClientProtocol实例引用了ClientFactory实例,这意味着它具有对ServerProtocol实例的引用。
  • 我添加了方法ClientProtocol可以用来指导ServerProtocol做任何你的应用逻辑,一旦ClientProtocol连接建立。请注意,由于前一点,ClientProtocol调用此方法没有任何问题。
+0

谢谢您的参考。我正在尝试将其应用于我的程序(您之前实际发布的程序)。但是,我应该提到传出连接实际上是到服务器。也许这应该没有什么区别,但我想我应该指出这一点。非常感谢。 – Bohmian

+0

除了我以前的回复,似乎有区别,我试图将数据发送到另一台服务器而不是客户端。我尝试在上面的ServerProtocol中创建一个factory.serverconnections [],然后在ClientProtocol中使用它,以便我可以将数据从外部客户端连接传递到外部服务器连接,但是出现列表无法识别的错误在后者。我会继续尝试,但如果你能看到我的方式中明显的错误,请指出。 – Bohmian

+0

非常感谢您的帮助,并且花时间解释如何使用Twisted中的方法。这是一个非常漂亮和优雅的解决方案。谢谢! – Bohmian