python twisted man-in-the-middle implementation
Question: What I need is a sort of man-in-the-middle implementation: I need a server who
receives connections from clients (binary data with different lengths) and
forwards the stream to a server it connects to (acting as a client), and then
sends the data back from the server it is connected to, to the clients.  
  
It actually works standing between the clients and the servers, and passing
the data they exchange (which is a stream, so it continuously get from one
side and sends to the other one).  
The server is static, so it is always the same, and its address can even be
hardcoded; however when a client drops the connection, this server must also
drop the connection to the "real" server.  
  
I've been looking around, but couldn't find a solution or an example for such
a simple problem.  
  
The code I've made works actually, but I have not yet managed to find how to
put a reference into the server part that says "this is your assigned client",
or into the client that says "this is your server". Here's my code:  
  

    
    
    #!/usr/bin/env python
    
    from twisted.internet import protocol, reactor
    from twisted.protocols import basic
    
    client = None
    server = None
    
    class ServerProtocol(protocol.Protocol):
        def connectionMade(self):
            global server
            factory = protocol.ClientFactory()
            factory.protocol = ClientProtocol
            server = self
            reactor.connectTCP('localhost', 1324, factory)
    
        def dataReceived(self, data):
            global client
            client.transport.write(data)
    
    class ClientProtocol(protocol.Protocol):
        def connectionMade(self):
            global client
            # Here's the instance of the client
            client = self
    
        def dataReceived(self, data):
            global server
            server.transport.write(data)
    
    def main():
        import sys
        from twisted.python import log
        log.startLogging(sys.stdout)
        factory = protocol.ServerFactory()
        factory.protocol = ServerProtocol
    
        # Here's the instance of the server
        server = ServerProtocol
    
        reactor.listenTCP(2593, factory)
        reactor.run()
    
    if __name__ == '__main__':
        main()
    

Now, the point is that the instance can't be contained into the global
objects, and should be put inside the two classes: how?  


Answer: I've managed to solve the issue by myself and, for future references (or to
help anybody else who had this problem), here's the code I used to solve it.  
  
I think both my solution and the one kindly given by jedwards work; now I just
have to study his own a little more to be sure that what I've done is correct:
this is my first application using the Twisted framework and studying somebody
else's solution is the way to learn something new! :)  
  

    
    
    #!/usr/bin/env python
    
    from twisted.internet import protocol, reactor
    from twisted.protocols import basic
    
    class ServerProtocol(protocol.Protocol):
        def __init__(self):
            self.buffer = None
            self.client = None
    
        def connectionMade(self):
            factory = protocol.ClientFactory()
            factory.protocol = ClientProtocol
            factory.server = self
    
            reactor.connectTCP('gameserver16.gamesnet.it', 2593, factory)
    
        def dataReceived(self, data):
            if (self.client != None):
                self.client.write(data)
            else:
                self.buffer = data
    
        def write(self, data):
            self.transport.write(data)
            print 'Server: ' + data.encode('hex')
    
    class ClientProtocol(protocol.Protocol):
        def connectionMade(self):
            self.factory.server.client = self
            self.write(self.factory.server.buffer)
            self.factory.server.buffer = ''
    
        def dataReceived(self, data):
            self.factory.server.write(data)
    
        def write(self, data):
            self.transport.write(data)
            print 'Client: ' + data.encode('hex')
    
    def main():
        import sys
        from twisted.python import log
    
        log.startLogging(sys.stdout)
    
        factory = protocol.ServerFactory()
        factory.protocol = ServerProtocol
    
        reactor.listenTCP(2593, factory)
        reactor.run()
    
    if __name__ == '__main__':
        main()
    

