[Twisted-Python] simple tcpgate in Twisted

Hi, I need to write a simple TCP/IP gate which would accept connections, reconnect to arbitrary (address,port), retransmit all data from both ends, and finally closed the connection upon either end closing it too. I was not able to find anything ready so I wrote a simple piece of the code (attached at the end along with the tcpecho used for testing purposes, for initiator side I use simply telnet). I also want to be as clean as possible from Twisted perspective. There are two problems I have encountered related to the cleanness of the solution: 1- I store self.gate_server_protocol in both GateClientProtocol(Protocol) and GateClientProtocolFactory(ClientFactory) This is an obvious redundancy, but it is not clear for me what is a relationship between a Protocol and a ClientFactory. Is it composition or aggregation, is it 1:1 or n:n. Is Factory created for each Protocol? 2 - Not sure id the relationship between GateServerProtocol and GateClientProtocol is correctly coded too. The prototype does not accumulate the data in case a connection for is GateClientProtocol not established. I will finish it of once I am confident the main structure is solid. Thx in advance for comments and sugestuions, AndyL -----------<CUT HERE>--------------- tcpgate.py ========== from twisted.internet.protocol import Protocol,ClientFactory,ServerFactory from twisted.internet import reactor class GateClientProtocol(Protocol): def __init__(self,gate_server_protocol): self.gate_server_protocol=gate_server_protocol gate_server_protocol.gate_client_protocol=self def connectionLost(self,reason): print 'GateClientProtocol.connectionLost',reason self.gate_server_protocol.transport.loseConnection() def dataReceived(self,data): self.gate_server_protocol.transport.write(data) class GateClientProtocolFactory(ClientFactory): def __init__(self,gate_server_protocol): self.gate_server_protocol=gate_server_protocol def buildProtocol(self,addr): print 'GateClientProtocolFactory:buildProtocol' return GateClientProtocol(self.gate_server_protocol) def clientConnectionFailed(self,connector,reason): print 'GateClientProtocolFactory:clientConnectionFailed',reason class GateServerProtocol(Protocol): def __init__(self): self.gate_client_protocol=None def connectionMade(self): print 'GateServerProtocol.connectionMade' reactor.connectTCP('127.0.0.1',8002,GateClientProtocolFactory(self)) def connectionLost(self,reason): print 'GateServerProtocol.connectionLost',reason if self.gate_client_protocol: self.gate_client_protocol.transport.loseConnection() self.gate_client_protocol=None def dataReceived(self,data): if self.gate_client_protocol: self.gate_client_protocol.transport.write(data) factory=ServerFactory() factory.protocol=GateServerProtocol reactor.listenTCP(8001,factory) reactor.run() tcpecho.py ========== from twisted.internet.protocol import Protocol,Factory from twisted.internet import reactor class Echo(Protocol): def connectionLost(self, reason): print 'Lost connection. Reason:', reason def dataReceived(self, data): print 'Echo:',`data` if 'quit' in data: self.transport.loseConnection() else: self.transport.write(data) factory=Factory() factory.protocol=Echo reactor.listenTCP(8002,factory) reactor.run()

On Wed, 06 Feb 2008 09:03:11 -0600, Andy Leszczynski <leszczynscy@yahoo.com> wrote:
twisted.protocols.portforward probably does something quite similar to what you want.
The relationship is up to the factory. In your code:
It seems the relationship is 1:1. Each time you want to establish a new connection, you create a new GateClientProtocolFactory instance and there is no reconnection logic implemented by GateClientProtocolFactory. You may see simplification by using twisted.internet.protocols.ClientCreator instead of having GateClientProtocolFactory.
2 - Not sure id the relationship between GateServerProtocol and GateClientProtocol is correctly coded too.
It seems basically correct, aside from the timing/connecting issue you mentioned.
Jean-Paul

On Wed, 06 Feb 2008 09:03:11 -0600, Andy Leszczynski <leszczynscy@yahoo.com> wrote:
twisted.protocols.portforward probably does something quite similar to what you want.
The relationship is up to the factory. In your code:
It seems the relationship is 1:1. Each time you want to establish a new connection, you create a new GateClientProtocolFactory instance and there is no reconnection logic implemented by GateClientProtocolFactory. You may see simplification by using twisted.internet.protocols.ClientCreator instead of having GateClientProtocolFactory.
2 - Not sure id the relationship between GateServerProtocol and GateClientProtocol is correctly coded too.
It seems basically correct, aside from the timing/connecting issue you mentioned.
Jean-Paul
participants (2)
-
Andy Leszczynski
-
Jean-Paul Calderone