threads/sockets quick question.

E

ed

this script should create individual threads to scan a range of IP
addresses, but it doesnt, it simple ... does nothing. it doesnt hang
over anything, the thread is not being executed, any ideas anyone?
----------

import socket
import threading
import traceback


MAX_THREADS = 50


class scanThread(threading.Thread):
def run(self):
try:
ss = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ss.connect((ip, port_counter))
print "%s | %d OPEN" % (ip, port_counter)
ss.close()
print "scanned: ",port_counter,"\n"
except:
traceback.print_exc()
# end class -------------------


def scan(ip, begin, end):
port_counter = 0
for port_counter in range(begin, end):
while threading < MAX_THREADS:
scanThread().start()
# end function -------------------
scan("localhost", 0, 10000)
 
B

Bryan Olson

ed said:
this script should create individual threads to scan a range of IP
addresses, but it doesnt, it simple ... does nothing. it doesnt hang
over anything, the thread is not being executed, any ideas anyone?

It's because of the bugs. Nothing happens because

threading < MAX_THREADS

is always false. You are comparing a module to an int. Next,
you never create any instances of scanThread. Next the local
variables of scan() are not visible in scanThread.run().
 
E

ed

import socket
import threading
import traceback


class scanThread(threading.Thread):
def run(self):
try:
ss = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ss.connect((ip, port_counter))
print "%s | %d OPEN" % (ip, port_counter)
ss.close()
print "scanned: ",port_counter,"\n"
except:
traceback.print_exc()
# end class -------------------


def scan(ip, thebegin, theend):
global ip
global thebegin
global theend
port_counter = 0
for port_counter in range(thebegin, theend):
scanThread().start()
# end function -------------------
scan("localhost", 0, 10000)
 
F

Fredrik Lundh

Bryan said:
Next, you never create any instances of scanThread.

one would think that the "scanThread()" part of

scanThread().start()

would do exactly that.

</F>
 
P

Piet van Oostrum

BO> It's because of the bugs. Nothing happens because
BO> threading < MAX_THREADS
BO> is always false. You are comparing a module to an int. Next,
BO> you never create any instances of scanThread. Next the local
BO> variables of scan() are not visible in scanThread.run().

And even if they were (for example if port_counter is made global), you
can't rely on it having the intended value in scanThread.run. You should
pass the port_number as a parameter to the thread.

And if the test for the number of threads was done properly, it would
swallow up all available threads for one port_number, rather than starting
one thread per port_number. And it doesn't handle the case when the threads
are exhausted: it should wait until a thread becomes available before
continuing.
 
P

Piet van Oostrum

ed said:
import socket
import threading
import traceback
def scan(ip, thebegin, theend):
global ip
global thebegin
global theend

Making parameters global is a bad idea (I think). Moreover, thebegin and
theend aren't used in scanThread. And port_counter still isn't passed.
Better give all required data as parameters to the scanThread constructor.

Something like:

class scanThread(threading.Thread):
def __init__(self, ip, port):
self.ip, self.port = ip, port
def run(self):
... use self.ip and self.port instead of ip and port_counter
port_counter = 0
for port_counter in range(thebegin, theend):
scanThread().start()
scanThread(ip, port_number).start()
# end function -------------------
scan("localhost", 0, 10000)

Now you're starting 10000 threads at the same time. Your OS probably won't
like that. Use a ThreadPool instead. Or divide the IP range into a number
of blocks, start a fixed number of threads, and give each thread a block of
IP numbers. The latter approach would be simpler IMO.
You may also have to take into account if your OS allows a maximum number
of open sockets for a process.
 
D

Dennis Lee Bieber

import socket
import threading
import traceback


class scanThread(threading.Thread):
def run(self):
try:
ss = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ss.connect((ip, port_counter))
print "%s | %d OPEN" % (ip, port_counter)
ss.close()
print "scanned: ",port_counter,"\n"
except:
traceback.print_exc()
# end class -------------------


def scan(ip, thebegin, theend):
global ip
global thebegin
global theend
port_counter = 0

All meaningless...

port_counter is redefined in the /for/ loop itself, so there is no
need to preset it to 0.

/global/ only makes items from OUTSIDE a function visible within the
function -- but your items ARE visible inside since they are the
arguments passed in... The class has no visibility to them.

The other problem I see is that... Depending on how the scheduler
operates, you could easily have port_counter CHANGE value between the
creation of the task, and the task actually trying to access it. Of
course, since IP and port_counter are not visible within the task, you
are attempting create a connection on (None, None).
for port_counter in range(thebegin, theend):
scanThread().start()
# end function -------------------
scan("localhost", 0, 10000)


How would I handle this? Pseudo-code (I don't have time to really
create this)...


job_queue = Queue.Queue(max_threads)

for j in range(max_threads):
#create and start a thread

for p in range(theBegin, theEnd):
job_queue.put((ip, p))

for j in range(max_threads):
job_queue.put("DIE!")
-=-=-=-=-
And each thread basically consists of:

global job_queue
while True:
param = job_queue.get()
if param == "DIE!": break
try:
ss = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ss.connect(param)
print "%s | %d OPEN" % param
ss.close()
print "scanned: %s \n" % param[1]
except:
traceback.print_exc()

In words: Create a global communication channel (the queue) from
which each task obtains its next assignment. Create all 50 (or whatever
limit you define) tasks -- each task will wait until an entry is
available on the queue, then process that entry, exiting if the entry is
the shutdown criteria. Main process then shoves assignments onto the
queue as fast as it can (up to the backlog limit -- you could have 50
tasks doing connections, and the main could have the next 50 assignments
queued). Finally, queue up enough shutdown messages so that each task is
assured of receiving at one.
--
 
A

antred

This may be a really stupid question, but are you actually CALLING your
scan() function anywhere?
 
A

antred

maybe try this

while threading.activeCount() < MAX_THREADS:
# ....


instead of

while threading < MAX_THREADS:
 
B

Bryan Olson

Fredrik said:
> Bryan Olson wrote:
>
>
>
> one would think that the "scanThread()" part of
>
> scanThread().start()
>
> would do exactly that.

And one would be correct.

I hereby retract that assertion of my post.
 
N

n00m

import socket
import thread

def scan(ip, port):
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, port))
s.close()
print '%s | %d OPEN \nscanned: %d' % (ip, port, port)
except:
pass

ip = 'localhost'
for port in range(50, 5000):
thread.start_new_thread(scan, (ip, port,))



This is the output on my machine:
localhost | 135 OPEN
scanned: 135

Traceback (most recent call last):
File "E:/*******.py", line 16, in -toplevel-
thread.start_new_thread(scan, (ip, port))
error: can't start new thread
scanned: 1027
localhost | 1029 OPEN
scanned: 1029


Btw I don't understand why many many the threads failed to start.
My box is quite powerful.
 
S

Simon Percivall

Why do you check if the module threading is less than 50? (this is why
nothing happens, it's always false).
From where do you get port_counter in method run() of scanThread? (this
would make every call to run() raise an exception.
 
D

dowskimania

ed said:
this script should create individual threads to scan a range of IP
addresses, but it doesnt, it simple ... does nothing. it doesnt hang
over anything, the thread is not being executed, any ideas anyone?
[SNIP]

while threading < MAX_THREADS:
scanThread().start()

In an interactive interpreter:
False

Since that tests as False, your code never enters the loop's body.

Christian
http://www.dowski.com
 
D

draghuram

The problem may be something to do with using "threading" as identifier
name. It is name of a module and definitely what you want it done
anyway. You are better off having another variable as counter (with a
different name).

Raghu.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top