Non blocking sockets with select.poll() ?

Maxim Veksler hq4ever at gmail.com
Sat May 5 08:37:31 EDT 2007


On 5/4/07, Jean-Paul Calderone <exarkun at divmod.com> wrote:
> >"""
> >#!/usr/bin/env python
> >import socket
> >import select
> >
> >class PollingSocket(socket.socket):
> >
> >
> >    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)
> >
> >    def poll(self, timeout = 0):
> >        return self.__poll.poll(timeout)
> >
> >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()
> >"""
> >
>
> This will only handle one connection at a time, of course.  The polling
> it does is also somewhat inefficient.  Perhaps that's fine for your use
> case.  If not, though, I'd suggest this version (untested):
>

Actually, I'm here to learn. I could have used any number of different
approaches to accomplish this; starting from
http://docs.python.org/lib/module-asyncore.html to twisted to
http://oss.coresecurity.com/projects/pcapy.html.

I would appreciate it if you could elaborate on why my loop is
inefficient, I will try to improve it then (and post back).

Besides, this whole story started from me writing a "quick
totalitarian" security testing framework. Once I'm done with the
networking part I will start working on the part that kill's all
current processes listening on TCP/IP of the machine. Obviously thats
not meant for production boxes... The simple idea is having the poller
on one side of the firewall connection and the "monster" on the other
side replying, a kind of primitive and plain firewall testing utility.

>   from twisted.internet import pollreactor
>   pollreactor.install()
>
>   from twisted.internet import reactor
>   from twisted.protocols.wire import Echo
>   from twisted.internet.protocol import ServerFactory
>
>   f = ServerFactory()
>   f.protocol = Echo
>   for i in range(10000, 19169):
>       reactor.listenTCP(i, f)
>   reactor.run()
>
> This will handle traffic from an arbitrary number of clients at the same
> time and do so more efficiently than the loop in your version.  You can
> also try epollreactor instead of pollreactor, if the version of Linux you
> are using supports epoll, for even better performance.
>

Thanks!

> Jean-Paul
>


-- 
Cheers,
Maxim Veksler

"Free as in Freedom" - Do u GNU ?



More information about the Python-list mailing list