Sockets

Jp Calderone exarkun at divmod.com
Thu May 5 09:19:21 EDT 2005


On Thu, 05 May 2005 17:11:08 +0800, Dan <dan at dontspammecauseidontlikit.com> wrote:
>
>
>I have a problem and I don't quite know how to implement the solution.
>
>I'll have a server application that will listen on a tcp port and make
>many similtaneous connections to remote clients.  From time to time,
>I'll need to write a small amount of data on one of those sockets.  A
>notification to write to one of the sockets will come from another
>program/process.
>
>I think that the best way to send the notification to this server
>application is via a udp message.  Alternatively, I could use tcp, but
>I don't think I'll need the extra complexity for what I want to do.
>(Other suggestions welcome.)

  UDP is actually more complex than TCP.  I recommend sticking with TCP until you have a better reason (eg, you need to communicate simultaneously with tens of thousands of clients).

>
>The server application will multiplex the connections using 'select',
>so much of the time it will be blocked on 'select'.
>
>My problem is how to also listen on a udp port while the process is
>blocked by 'select'.  Should I run a separate thread?  And if so can I
>share the socket connection across the two threads?  (Thread 1 will be
>accepting client connections, thread 2 will we writing data to it.)
>Or should I simply let 'select' time out after some period?
>
>I'm a bit lost as to how to do this, I hope someone can put me on the
>right track.  Any solution that I use should be applicable on Linux
>and Windows platforms.

  I recommend using Twisted.  Here's a sample application that accepts connections, waits on messages from each client, and then transmits another message to all other clients in response to receiving one (untested code):

    from twisted.internet import reactor, protocol
    from twisted.protocols import basic

    # Define the protocol with which we will handle all 
    # incoming connections
    class ClientMessageProtocol(protocol.LineReceiver):

        # When a connection is established, append this 
        # instance to the factory's list of connected 
        # clients, so it can send messages to this client 
        # when necessary.
        def connectionMade(self):
            self.factory.clients.append(self)

        # Likewise, remove the instance when the connection 
        # is lost.
        def connectionLost(self):
            self.factory.clients.remove(self)

        # Every time a whole line is received, tell the factory 
        # about it.
        def lineReceiver(self, line):
            self.factory.lineReceived(self, line)

    class ClientMessageFactory(protocol.ServerFactory):
        # Indicate the protocol to be instantiated for each
        # connection to this factory.
        protocol = ClientMessageProtocol

        # At startup, make an empty clients list.
        def startFactory(self):
            self.clients = []

        # Whenever a client tells us they received a line, send
        # a short message to every other connection client.
        def lineReceived(self, client, line):
            for cl in self.clientz:
                if cl is not client:
                    cl.sendLine("%s sent me a message: %r" % (client, line))

    # Start the server on TCP port 54321
    reactor.listenTCP(54321, ClientMessageFactory())

    # Run the main event loop
    reactor.run()

  Learn more about Twisted on its website: http://www.twistedmatrix.com/

  Jp



More information about the Python-list mailing list