Non blocking sockets with select.poll() ?

Jean-Paul Calderone exarkun at divmod.com
Sat May 5 11:55:41 EDT 2007


On Sat, 5 May 2007 15:37:31 +0300, Maxim Veksler <hq4ever at gmail.com> wrote:
>On 5/4/07, Jean-Paul Calderone <exarkun at divmod.com> wrote:
>> >"""
>> >#!/usr/bin/env python
>> >import socket
>> >import select
>> >
>> >class PollingSocket(socket.socket):
>> >

Usually there's no particularly good reason to subclass socket.  In this
case you did it to add a poll method, it seems.  However...

>> >
>> >    def __init__(self, port_number):
>> >        self.__poll = select.poll()
>> >        self.tcp_port_number = port_number
>> >
>> >        socket.socket.__init__(self, socket.AF_INET, socket.SOCK_STREAM)
>> >        self.setblocking(0)
>> >        self.bind(('0.0.0.0', self.tcp_port_number))
>> >        self.listen(5)
>> >        self.__poll.register(self)

Creating one poll object per socket isn't necessary.  You only need one
overall.

>> >
>> >    def poll(self, timeout = 0):
>> >        return self.__poll.poll(timeout)

Polling with a zero timeout is just busy looping.  You want to poll with a
large (or infinite) timeout, and on more than one socket at a time.

>> >
>> >def debugPollingSocket(port_num):
>> >    print "BIND TO PORT: ", port_num
>> >    return PollingSocket(port_num)
>> >
>> >all_sockets = map(debugPollingSocket, xrange(10000, 19169))
>> >
>> >print "We have this in stock:"
>> >for nb_active_socket in all_sockets:
>> >    print nb_active_socket.tcp_port_number
>> >
>> >while 1:
>> >    for nb_active_socket in all_sockets:
>> >        print "Asking", nb_active_socket.tcp_port_number
>> >        if nb_active_socket.poll(0):
>> >            print "Found", nb_active_socket.tcp_port_number
>> >            conn, addr = nb_active_socket.accept()
>> >            while 1:
>> >                data = conn.recv(1024)
>> >                if not data: break
>> >                conn.send(data)
>> >            conn.close()
>> >"""
>> >

Instead of looping over all the sockets repeatedly and asking each one if
it has any data, you want to create one poll object, register every socket
with it, and ask it which sockets have data.  You also want to put the
accepted sockets into non-blocking mode and also poll them, reading from
whichever ones have data when they have data.

Even if you don't want to use Twisted, it might be beneficial to read how
it is implemented to learn how to do this.

Jean-Paul



More information about the Python-list mailing list