start a multi-sockets server (a socket/per thread) with different ports but same host

Jean-Paul Calderone exarkun at divmod.com
Sat Aug 12 12:52:34 EDT 2006


On 12 Aug 2006 09:00:02 -0700, zxo102 <zxo102 at gmail.com> wrote:
>Hi,
>   I am doing a small project using socket server and thread in python.
> This is first time for me to use socket and thread things.
>   Here is my case. I have 20 socket clients.  Each client send a set
>of sensor data per second to a socket server.  The socket server will
>do two things: 1. write data into a file via bsddb; 2. forward the data
>to a GUI written in wxpython.
>   I am thinking the code should work as follow (not sure it is
>feasible)
>      20 threads, each thread takes care of a socket server with a
>different port.
>   I want all socket servers start up and wait for client connection.
>In the attached demo code, It stops at the startup of first socket
>server somewhere in the following two lines and waits for client call:
>

Threads aren't the best way to manage the concurrency present in this
application.  Instead, consider using non-blocking sockets with an
event notification system.  For example, using Twisted, your program
might look something like this:

from twisted.internet import reactor, protocol, defer

class CumulativeEchoProtocol(protocol.Protocol):
    def connectionMade(self):
        # Stop listening on the port which accepted this connection
        self.factory.port.stopListening()

        # Set up a list in which to collect the bytes which we receive
        self.received = []


    def connectionLost(self, reason):
        # Notify the main program that this connection has been lost, so
        # that it can exit the process when there are no more connections.
        self.factory.onConnectionLost.callback(self)

    def dataReceived(self, data):
        # Accumulate the new data in our list
        self.received.append(data)
        # And then echo the entire list so far back to the client
        self.transport.write(''.join(self.data))

def allConnectionsLost():
    # When all connections have been dropped, stop the reactor so the
    # process can exit.
    reactor.stop()

def main():
    # Set up a list to collect Deferreds in.  When all of these Deferreds
    # have had callback() invoked on them, the reactor will be stopped.
    completionDeferreds = []
    for i in xrange(20):
        # Make a new factory for this port
        f = protocol.ServerFactory()

        # Make a Deferred for this port's connection-lost event and make
        # it available to the protocol by way of the factory.
        d = defer.Deferred()
        f.onConnectionLost = d
        completionDeferreds.append(d)
        f.protocol = CumulativeEchoProtocol

        # Start listening on a particular port number with this factory
        port = reactor.listenTCP(2000 + i + 1, f)

        # Make the port object available to the protocol as well, so that
        # it can be shut down when a connection is made.
        f.port = port

    # Create a Deferred which will only be called back when all the other
    # Deferreds in this list have been called back.
    d = defer.DeferredList(completionDeferreds)

    # And tell it to stop the reactor when it fires
    d.addCallback(lambda result: allConnectionsLost())

    # Start the reactor so things can start happening
    reactor.run()

if __name__ == '__main__':
    main()

Hope this helps,

Jean-Paul



More information about the Python-list mailing list