Speed up with threads

Jonathan Hogg jonathan at onegoodidea.com
Mon Aug 5 10:52:04 CEST 2002


On 4/8/2002 22:23, in article Xns9260EE2F69FC3cliechtigmxnet at 62.2.16.82,
"Chris Liechti" <cliechti at gmx.net> wrote:

>>     def run(self):
>>         try:
>>             host, port = queue.get()
>>             # connect to the given host:port
>>             self.sd.connect((host, port))
>>             print "%s:%d OPEN" % (host, port)
>>             self.sd.close()
> 
> i'm not sure if you can close a socket and connect afterwards again... i
> would create the socket object in the loop. but mayve an expert can speak
> up here.

It seems to me that the main problem here is that there is no loop. The
important thing with worker threads is that they *repeatedly* ask for some
work to do and then go away and do it.

Here's my solution. Just for kicks I put the results into another queue as
they are obtained and then pull them back out in the main function and
re-order them before printing them.

----------------------------------------------------------------

import socket, threading, Queue


class Scanner( threading.Thread ):

    def __init__( self, inq, outq ):
        threading.Thread.__init__( self )
        self.setDaemon( 1 )
        self.inq = inq
        self.outq = outq

    def run( self ):
        while 1:
            host, port = self.inq.get()
            s = socket.socket()
            try:
                s.connect( (host, port) )
            except socket.error:
                self.outq.put( (host, port, 'CLOSED') )
            else:
                self.outq.put( (host, port, 'OPEN') )
                s.close()


def scan( host, start, end, nthreads=50 ):

    toscan = Queue.Queue()
    scanned = Queue.Queue()

    scanners = [ Scanner(toscan, scanned) for i in range(nthreads) ]
    for scanner in scanners:
        scanner.start()

    hostports = [ (host, port) for port in xrange(start, end+1) ]
    for hostport in hostports:
        toscan.put( hostport )

    results = {}
    for host, port in hostports:
        while (host, port) not in results:
            nhost, nport, nstatus = scanned.get()
            results[(nhost, nport)] = nstatus
        status = results[(host, port)]
        if status <> 'CLOSED':
            print '%s:%d %s' % (host, port, status)


if __name__ == '__main__':
    scan( 'localhost', 0, 1024 )

----------------------------------------------------------------

Jonathan




More information about the Python-list mailing list