Skip navigation.
Home

Reply to comment

Async python Socket Server using gobject

Recently I created a small command line python utility to process some stuff on a TCP socket connection. I used the standard python SocketServer class because it was dead simple to use for my purposes.

However, as the requirements of the utility grew (a GUI), I hit the main problem with SocketServers - they block - which is not so good for GUIs.

So, instead of using nasty old threading, I worked out how to use gobject.io_add_watch() to do everything in the gobject/gtk main loop. This makes it very simple to have this run in a gtk UI without needing threads.

The basic pattern is shown below. The first function, server(), sets up the socket (bind, listen) and waits for connections, but doesn't block. Instead it sets a watch and when a new connection comes in it calls a listener(). This accepts the new connection and creates a handler(). The handler is called whenever input is available on the connection. Note that listener and handler return True (typically) so that the io_watch keeps running. After a connection is closed, the listener is called again to create a new connection.

It took me a while to work this out and I couldn't find all of this in one place on the web, so here it is. Hope it helps someone.

import gobject, socket
 
def server(host, port):
	'''Initialize server and start listening.'''
	sock = socket.socket()
	sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
	sock.bind((host, port))
	sock.listen(1)
	print "Listening..."
	gobject.io_add_watch(sock, gobject.IO_IN, listener)
 
 
def listener(sock, *args):
	'''Asynchronous connection listener. Starts a handler for each connection.'''
	conn, addr = sock.accept()
	print "Connected"
	gobject.io_add_watch(conn, gobject.IO_IN, handler)
	return True
 
 
def handler(conn, *args):
	'''Asynchronous connection handler. Processes each line from the socket.'''
	line = conn.recv(4096)
	if not len(line):
		print "Connection closed."
		return False
	else:
		print line
		return True
 
 
if __name__=='__main__':
	server('', 8080)
	gobject.MainLoop().run()

Reply

  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <h1> <h2> <h3> <h4> <img> <pre> <b> <i> <blockquote>
  • Lines and paragraphs break automatically.
  • Link to content with [[some text]], where "some text" is the title of existing content or the title of a new piece of content to create. You can also link text to a different title by using [[link to this title|show this text]]. Link to outside URLs with [[http://www.example.com|some text]], or even [[http://www.example.com]].
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>.

More information about formatting options