2017-02-04 9 views
0

Я пытаюсь сделать сканер портов с резьбой, но он не работает так, как я ожидал. Код при создании вывода генерирует искаженный вывод. Я знаю, что это связано с тем, что некоторые потоки закончили перед другими, чтобы они печатали свой вывод на экран, но я не знаю, как его предотвратить.Сканер портов Python, производящий искаженный вывод

import threading 
import socket 

portlist = [21,22,25,80,110,443] 
open = [] 
closed = [] 
failed = 0 
length = 0 
ip = None 
site_ = None 
ip = None 
def portscan(site,port): 
    global failed 
    global length 
    global failed 
    global length 
    global ip 
    global site_ 
    try: 
     socket.setdefaulttimeout(2) 
     s = socket.socket() 
     s.connect((site,port)) 
     open.append(port) 
     s.close() 
     print("[SCANNING...]") 
    except: 
     closed.append(port) 
     failed = failed + 1 
     print("[SCANNING...]") 
    length = length + 1 

def statistics(): 
    try: 
     avg = failed/length*100 
    except: 
     avg = 0 
    print("<PORTS OPEN>") 
    print(open) 
    print("<PORTS CLOSED>") 
    print(closed) 
    print("PACKETS SENT:",length,"| PACKETS LOST:",failed,"[",avg,"% loss]") 

def main(): 
    site_ = input("/ENTER SITE IP OR NAME/>") 
    try: 
     ip = socket.gethostbyname(site_) 
    except: 
     ip = "COULD NOT GET IP" 
    for port in portlist: 
     t = threading.Thread(target = portscan, args = (site_,port)) 
     t.start() 
    print("<---SCAN STATISTICS FOR",site_,"[",ip,"] RETURNED--->") 
    statistics() 

if __name__ == "__main__": 
    main() 

wait = input("") 

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

<---SCAN STATISTICS FOR www.gmail.com [ 74.125.68.18 ] RETURNED---> 
<PORTS OPEN> 
[] 
<PORTS CLOSED> 
[] 
PACKETS SENT: 0 | PACKETS LOST: 0 [ 0 % loss] 
[SCANNING...] 
[SCANNING...] 
[SCANNING...] 
[SCANNING...] 
[SCANNING...] 
[SCANNING...] 

То, что я хочу это потоки, которые будут завершены до того, как будут распечатаны порты.

+0

Чтобы лучше помочь вам вы можете предоставить неверный вывод также? Я сомневаюсь, что многие пользователи SO занимают время, чтобы выполнить ваш скрипт. – tiblu

+0

Также стоит отметить, что глобальные переменные, используемые разными потоками, должны быть синхронизированы, чтобы избежать недопустимых данных - http://effbot.org/zone/thread-synchronization.htm – tiblu

ответ

1

Вы должны ждать (вызов .join) для нитей, чтобы закончить

threads = [] 
for port in portlist: 
    t = threading.Thread(target = portscan, args = (site_,port)) 
    t.start() 
    threads.append(t) 
#now wait for them to finish 
for t in threads: 
    t.join()