3

I am having issues with a port scanner I'm editing to use threads. This is the basics for the original code:

for i in range(0, 2000):  

    s = socket(AF_INET, SOCK_STREAM)  
    result = s.connect_ex((TargetIP, i))  

    if(result == 0) :  
        c = "Port %d: OPEN\n" % (i,)  

    s.close()

This takes approx 33 minutes to complete. So I thought I'd thread it to make it run a little faster. This is my first threading project so it's nothing too extreme, but I've ran the following code for about an hour and get no exceptions yet no output. Am I just doing the threading wrong or what?

import threading
from socket import *
import time

a = 0
b = 0
c = ""
d = ""

def ScanLow():
    global a
    global c

    for i in range(0, 1000):  
        s = socket(AF_INET, SOCK_STREAM)  
        result = s.connect_ex((TargetIP, i))  

        if(result == 0) :  
            c = "Port %d: OPEN\n" % (i,)  

        s.close()  
        a += 1

def ScanHigh():
    global b
    global d

    for i in range(1001, 2000):  
        s = socket(AF_INET, SOCK_STREAM)  
        result = s.connect_ex((TargetIP, i))  

        if(result == 0) :  
            d = "Port %d: OPEN\n" % (i,)  

        s.close()  
        b += 1

Target = raw_input("Enter Host To Scan:")
TargetIP = gethostbyname(Target)

print "Start Scan On Host ", TargetIP
Start = time.time()

threading.Thread(target = ScanLow).start()
threading.Thread(target = ScanHigh).start()

e = a + b

while e < 2000:
    f = raw_input()

End = time.time() - Start
print c
print d
print End

g = raw_input()
moinudin
  • 134,091
  • 45
  • 190
  • 216
Amnite
  • 221
  • 1
  • 4
  • 9
  • It's not your main problem (see answer(s) below), but note that your revision isn't checking port `1000` unlike the original. – martineau Jan 09 '11 at 18:03

2 Answers2

5

This is where your code is failing.

threading.Thread(target = ScanLow).start()
threading.Thread(target = ScanHigh).start()

e = a + b

while e < 2000:
   f = raw_input()

Immediately after you start your threads, you set the value to e. However, you never update e after that, so the loop never exits.

It also seems like you are doing this to wait until both threads have finished. The join() method is is a better way to do this.

from threading import Thread
threads = []
threads.append(Thread(target = ScanLow))
threads.append(Thread(target = ScanHigh))
for thread in threads:
  thread.start()
//both threads are running
for thread in threads:
  thread.join()
//both threads have stopped

Edit: Not related to your question, but a helpful comment. Both of your scan functions are doing the exact same thing. You can replace them with one function that takes the scan range as arguments and start both threads with the one function.

from threading import Thread
def Scan(start, stop):
    global a
    global c

    for i in range(start, stop):  
        s = socket(AF_INET, SOCK_STREAM)  
        result = s.connect_ex((TargetIP, i))  

        if(result == 0) :  
            c = "Port %d: OPEN\n" % (i,)  

        s.close()  
        a += 1

threadCount = 2
totalPorts = 2000
threads = []
for start in xrange(0, totalPorts, totalPorts/threadCount):
    threads.append(Thread(target = Scan, args = (start, totalPorts/threadCount)))

for thread in threads:
  thread.start()
//both threads are running
for thread in threads:
  thread.join()
//both threads have stopped

And now you can easily adjust the number of threads and ports to scan.

unholysampler
  • 17,141
  • 7
  • 47
  • 64
  • threads.append(Thread(target = Scan, args = (start, totalPorts/threadCount))) NameError: Name "Thread" is not defined I didnt think to mention this but maybe we're not using same Python version I use 2.6 – Amnite Jan 09 '11 at 18:38
  • Sorry. Total newb moment. I changed Import threading to from threading import *. That worked. Thank you very much for your help. It works great and I learned alot more about threading(Though I'm still researching some specifics of your code.) TY TY TY – Amnite Jan 09 '11 at 18:53
1

You have an awkward method for monitoring the threads. Using join will indicate when the thread is complete. No reason not to spin off more threads to get the results faster as well:

import threading
import socket
import time

ports = []
def check_port(ip,port):
    s = socket.socket()
    if s.connect_ex((ip,port)) == 0:
        ports.append(port)
    s.close()

target = raw_input('Target? ')
s = time.time()
threads = []
for port in range(2000):
    t = threading.Thread(target=check_port,args=(target,port))
    t.start()
    threads.append(t)
for t in threads:
    t.join()
print ports
print time.time() - s

Output

[80, 135, 445, 1028]
6.92199993134
Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251