私は単純なマルチスレッドポートスキャナを作っています。ホスト上のすべてのポートをスキャンし、開いているポートを返します。問題がスキャンを中断しています。スキャンが完了するまでに多くの時間がかかり、時にはスキャンの途中でC-cでプログラムを終了させたい場合があります。問題はスキャンが停止しないことです。キューからのすべてのデータが処理され、メインスレッドをデブロッキングしてプログラムを正常に終了するまで、メインスレッドはqueue.join()でロックされ、KeyboardInterruptは無視されます。すべてのスレッドはデーモン化されているので、メインスレッドが死んだら、彼と一緒に死ぬべきです。Python - KeyboardInterruptでメインスレッドを終了できません
私は信号libを使ってみましたが、成功しませんでした。 queue.join実行中threading.Threadクラスをオーバーライドして動作しませんでした優雅な終了のためのメソッドを追加...メインスレッドだけでKeyboardInterruptを受信しません()
import threading, sys, Queue, socket
queue = Queue.Queue()
def scan(host):
while True:
port = queue.get()
if port > 999 and port % 1000 == 0:
print port
try:
#sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#sock.settimeout(2) #you need timeout or else it will try to connect forever!
#sock.connect((host, port))
#----OR----
sock = socket.create_connection((host, port), timeout = 2)
sock.send('aaa')
data = sock.recv(100)
print "Port {} open, message: {}".format(port, data)
sock.shutdown()
sock.close()
queue.task_done()
except:
queue.task_done()
def main(host):
#populate queue
for i in range(1, 65536):
queue.put(i)
#spawn worker threads
for port in range(100):
t = threading.Thread(target = scan, args = (host,))
t.daemon = True
t.start()
if __name__ == '__main__':
host = ""
#does input exist?
try:
host = sys.argv[1]
except:
print "No argument was recivied!"
exit(1)
#is input sane?
try:
host = socket.gethostbyname(host)
except:
print "Adress does not exist"
exit(2)
#execute main program and wait for scan to complete
main(host)
print "Post main() call!"
try:
queue.join()
except KeyboardInterrupt:
print "C-C"
exit(3)
はEDIT:
私が発見しました時間のモジュールを使用してソリューション。
#execute main program and wait for scan to complete
main(host)
#a little trick. queue.join() makes main thread immune to keyboardinterrupt. So use queue.empty() with time.sleep()
#queue.empty() is "unreliable" so it may return True a bit earlier then intented.
#when queue is true, queue.join() is executed, to confirm that all data was processed.
#not a true solution, you can't interrupt main thread near the end of scan (when queue.empty() returns True)
try:
while True:
if queue.empty() == False:
time.sleep(1)
else:
break
except KeyboardInterrupt:
print "Alas poor port scanner..."
exit(1)
queue.join()
誰もが知っています?これは1トンのCPUを無駄にし、スレッドをスレッドを使用してしばらくの間Trueを回避します。 'thread.join'は、(CPU時間を無駄にする無限ループなしで)私がそれを殺すことができれば、完璧です。何か案は?しかし、私が実行しているテストでは、テスト目的と将来の参照のためにスレッドが無期限に(理論的には永遠に)続けるため、スレッドを終了する必要はありません(別の用語で 'pkill python'を実行するのは苦痛です。私は本当に知りたいです。ありがとう(とCtrl + Zをしないでください) – dylnmc
これはWindows上で実行している場合、これは "正常"です。 PythonインタプリタはCTRL-Cをキャッチして内部フラグをセットし、制御がPythonの解釈に戻るのを待って 'KeyboardInterrupt'を発生させます。それは、内部フラグをチェックし戻すために 'EINTR'を返すシステムコールをブロックすることに頼っています。しかし、Windowsでのシステムのブロック操作は、そのようなことが起こったときに 'EINTR'エラーコードで返されないので、' KeyboardInterrupt'例外は、ブロック操作が完了するまで延期されます。 –