[Twisted-Python] simple tcpgate in Twisted

Andy Leszczynski leszczynscy at yahoo.com
Wed Feb 6 10:03:11 EST 2008


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








More information about the Twisted-Python mailing list