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