Problem using SocketServer.ThreadingTCPServer on Windows?

Panu A Kalliokoski pkalliok at cc.helsinki.fi
Thu May 31 13:26:31 CEST 2001


xtian <xtian at paradise.net.nz> wrote:

> Obviously, the only way to get more than one connection at a time to a
> server using synchronous sockets is by using multithreading.

Ah! You're planning on using threads. I didn't understand that, it didn't 
cross my mind at all... I'm so used to using select(). It's a lot easier 
to use, if you ask me.

People use the words synchronous and asynchronous very misleadingly. In 
today's world, there are at least four alternatives to make a multiplexing 
server:

- synchronous one-socket server with UDP; has to do the bookkeeping of 
  open UDP "connections" itself
- asynchronous threaded server with synchronous, non-multiplexed threads 
  with one socket each (your choice, if I understand correctly)
- syncronous, threaded multiplexed server with select() (my choice)
- asynchronous multiplexed server with data delivery notifications, 
  usually signals.

> Granted, an asynchronous framework would give better scalability, but
> the concepts are a bit more complicated, as far as I've seen. There

It's all about how you're used to doing it. Threaded servers bring subtle 
race conditions in inter-thread communications and locking. It's not an 
insoluble problem, but neither is select()ing. For me, select()ing is both 
better scalable and easier to use.

> are lots of examples in Java using the same structure I'm using,
> presumably because they're conceptually very simple. 

For me, it seems simple on the I/O side and very complex on the internal 
communications side. But this is a standard holy war issue, so no point 
arguing (I hope I'm not doing that).

> Actually, I hadn't even looked at asynchat - it might be just what I
> need. I've downloaded your selecting package - can you give examples
> of how it might be used? I'm not really familiar with asynchronous
> networking.

The TCPServer is used like this: 

class MyChannelHandler (ChannelHandler):
	def receive(s, data):
		# do something with data
	def reg_conn(s, conn):
		s.conn = conn
	def send(s, data):
		s.conn.write(data)

class MyHandlerFactory:
	def new_conn_handler(s):
		return MyChannelHander()

mgr = SelectManager()
mgr.add_channel(ServerSocket(('', SERVER_PORT), MyHandlerFactory())
mgr.loop()

Everytime the ServerSocket gets a connection, it builds a new channel with
a new channel handler (which you get to define in MyChannelHandler). The
receive() callback of the channel handlers is called upon reception of
data. Any data can be sent back to the connection by calling the channel
handler's send() (which moves the data forth to connection's write()). And
this all happens in one thread, so that you can know there's only one
receive() call taking place at any time.

Panu Kalliokoski




More information about the Python-list mailing list