2014-02-25 42 views
0

我最近开始使用Python Twisted,虽然它非常复杂,但我真的很喜欢它!我试图寻找答案,但我一直在干,所以我希望有人在这里是一个扭曲的大师:Python在运行时发送数据包的扭曲动态协议

我有一个大型/复杂的分布式系统设置的分层格式与主人,奴隶,子从,等。 在我的代码取决于收到的数据包中的几个点,我需要发送一个数据包到另一个节点。数据需要发送到的节点在调用reactor.run()之前未知,所以我觉得答案可能会有所不同。我希望连接是可靠的TCP,但它只需要发送一个数据包。有时我需要回复ACK,有时我不需要,但之后连接总是会死掉。目前的办法,我已经处理这个是通过保持在班里reactor所需要发送的数据包的引用,并美其名曰:

tmpConn = MyClientFactory(dataToSend) 
self.reactor.connectTCP(ADDR, PORT, tmpConn) 

我觉得这可能然而,存在的几个问题:

  • 如果我不保留对tmpConn的引用,垃圾回收会发生什么。
  • 如果我在我的课程中保留对它的引用,它最终会成为垃圾,因为它只需要发送一个数据包。

正如我所说的,有很多不同的工厂都在同一时间做这样的事情,所以我不知道这是否是处理这种情况的最好方法。任何指针都非常感谢。

这是一段代码,所以问题更加清晰。

from twisted.internet import reactor 
from twisted.internet.protocol import Protocol, Factory, ClientFactory 

class OneShotProtocol(Protocol): 
    def __init__(self, addr, data): 
     self.myaddr = addr 
     self.mydata = data 

    def connectionMade(self): 
     # We know we have a connection here so send the data 
     self.transport.write(self.mydata) 
     # Now we can kill the connection 
     self.transport.loseConnection() 

class OneShotFactory(ClientFactory): 
    def __init__(self, data): 
     self.mydata = data 

    def buildProtocol(self, addr): 
     return OneShotProtocol(addr, self.mydata) 

class ListenProtocol(Protocol): 
    def __init__(self, addr, factory): 
     self.myaddr = addr 
     #NOTE: I only save this because I've read multiple reactors are possible 
     self.factory = factory 

    def dataReceived(self, data): 
     if(data == 'stuff'): 
      #Alert the other node! 
      tmpConn = OneShotFactory('The British are coming') 
      self.factory.reactor.connectTCP(ADDR, PORT, tmpConn) 
     # Moving on... 

class ListenFactory(Factory): 
    def __init__(self, reactor): 
     self.reactor = reactor 

    def buildProtocol(self, addr): 
     return OneShotProtocol(addr, self) 

l = ListenFactory(reactor) 
reactor.listenTCP(PORT, l) 
reactor.run() 

回答

0

这听起来像是一种实现所需行为的好方法。

您不必非常担心工厂的垃圾收集。反应堆会保留一个参考(毕竟,你通过它到connectTCP),只要它需要,然后忘记它。如果你也忘记了它,那么Python的垃圾回收器会在太久之前为你清理它。

您可能想要做的唯一调整是使用酷新的"endpoint" APIs而不是使用connectTCP目录。这并没有改变解决方案的基本思想,它只是给你一点灵活性,你可能有一天会从中受益。

相关问题