2013-05-27 2 views
2

Да, да, я знаю, что могу просто использовать nmap, но я хочу попробовать это сам.Сканер многопоточного порта

Я пытаюсь написать сценарий с резьбой, чтобы найти открытые порты на целевом IP-адресе. Это то, что я прямо сейчас:

import socket, Queue 
from threading import Thread 


print "Target to scan: " 
targetIP = raw_input("> ") 
print "Number of threads: " 
threads = int(raw_input("> ")) 


q = Queue.Queue() 

# Fill queue with port numbers 
for port in range(1, 1025): 
    q.put(port) 


def scan(targetIP, port): 
    try: 
     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     s.settimeout(4) 
     result = s.connect_ex((targetIP, port)) 
     if result == 0: 
      print 'Port {0} is open'.format(port) 
     s.close 
     q.task_done() 



while q.full: 
    for i in range(threads): 
     port = q.get() 
     t = Thread(target=scan, args =(targetIP, port)) 
     t.daemon = True 
     t.start() 

Однако у меня есть несколько вопросов:

1) Когда я запускаю это как есть, он будет перебирать очереди порта, но потом просто повесить, никогда не вырывается из цикл while, даже если очередь опустошается.

2) Если добавить печатную строку scan, чтобы увидеть Что происходит, в основном добавить «Сканирование порта X» линии в начале и print result строку в конце, стандартный вывод затопляется с линией «Сканирование порта» для все порты в очереди, и THEN выводятся строки результатов. Смысл, похоже, что в настоящее время скрипт не ждет result, чтобы получить значение, и просто продолжайте итерацию, как если бы она была.

Что я здесь делаю неправильно?

+0

'Значение, похоже, в настоящее время сценарий не ждет результата, чтобы получить значение, и просто продолжайте итерацию, как если бы это было. »Значение, скрипт работает в нескольких потоках, а не последовательно? Разве это не то, что вы хотели в первую очередь? –

+0

Ожидание до тех пор, пока 'q.full' не будет ложным. Вы не вызываете функцию ... –

ответ

2

У вас есть несколько проблем здесь, во-первых:

while q.full: 

Предположительно вы хотели вызова функция:

while q.full(): 

Но у вас есть бесконечная очередь (вы создали его нет maxsize), поэтому он никогда не бывает полным; поэтому, если вы сделаете это изменение, он вообще не вызовет scan().

Предположим, вы исправите это каким-либо другим способом (например, используя q.empty()), что произойдет, если range(threads) не равномерно разделяет элементы в очереди? Например, предположим, что вы используете 3 потока и поместите номера портов 1, 2, 3 и 4 в q. Вы вызовете q.get() три раза (получение 1, 2 и 3) в первом проходе через внешний while, а затем вызовите его три раза снова во втором отключении, но в нем есть еще одно значение, 4, поэтому вызов q.get() после этого будет ждать, пока кто-то выполнит q.put(), и вы застрянете.

Вам нужно переписать логику, другими словами.

Редактировать: проблема с s.close vs s.close(). Другие рассмотрели весь аспект пула нитей[email protected] Версия Blender, используя multiprocessing, намного проще, так как multiprocessing позаботится об этом для вас.

0

Ну, вы должны знать, что, просто повторяя номера в диапазоне от количества потоков и выполняя поток, вы не сохраняете количество нужных потоков. Он просто петли 4 раза, создает 4 потока, петли снова и входит в один и тот же цикл и создает еще 4, не будучи уверенным, что эти 4 завершили свою задачу, поэтому вы получаете этот поток сообщений, когда вы помещаете отпечатки в функцию сканирования.

Вам придется подождать, пока дети закончит работу в конце части тела.

Я думаю:

threading.wait() 

делает вещь.

1

С кодом есть несколько проблем. Во-первых, цикл while продолжается до q.full, который является функцией, является ложным. Но на самом деле нет необходимости зацикливаться в основной теме.

Я бы добавил значения дозорных значений в конец очереди, по одному на рабочий поток. Когда рабочий поток получает дозорный сигнал, он завершает цикл обработки. Таким образом, вам не нужно демонизировать потоки.

Таким образом, вы код должен быть как:

  • нанесенных порты в очередь
  • поставил сторожей в очередь
  • запустить нужное количество потоков, у них принимают порты из очереди и обрабатывать их, положить результаты в другой очереди
  • ожидания для потоков оканчиваются, вызывая t.join() на рабочих
  • используют результаты
4

Ваш актуальный вопрос уже ответили несколько человек, так вот альтернативное решение с multiprocessing.Pool вместо threading:

import socket 

from multiprocessing import Pool 

def scan(arg): 
    target_ip, port = arg 

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    sock.settimeout(2) 

    try: 
     sock.connect((target_ip, port)) 
     sock.close() 

     return port, True 
    except (socket.timeout, socket.error): 
     return port, False 

if __name__ == '__main__': 
    target_ip = raw_input('Target IP: ') 
    num_procs = int(raw_input('Number of processes: ')) 

    ports = range(1, 1025) 
    pool = Pool(processes=num_procs) 

    for port, status in pool.imap_unordered(scan, [(target_ip, port) for port in ports]): 
     print port, 'is', 'open' if status else 'closed' 
-1

Попробуйте это:

import socket 
import threading 
from queue import Queue 

print_lock = threading.Lock() 

target = 'pythonprogramming.net' 

def portscan(port): 
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    try: 
     con = s.connect((target,port)) 
     with print_lock: 
      print('port',port,'is open!') 
     con.close() 
    except: 
     pass 

def threader(): 
    while True: 
     worker = q.get() 
     portscan(worker) 
     q.task_done() 

q = Queue() 

for x in range(30): 
    t = threading.Thread(target=threader) 
    t.daemon = True 
    t.start() 


for worker in range(1,10000): 
    q.put(worker) 

q.join() 
+0

Ваш ответ должен содержать объяснение вашего кода и описание того, как он решает проблему. – AbcAeffchen

Смежные вопросы