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、キューが空になってもループから抜け出すことはありません。

scan2)何が起こっているかを確認するために印刷行を追加すると、基本的に最初に「スキャンポートX」行を追加print resultし、最後に行を追加すると、stdoutはキュー内のすべてのポートの「スキャンポート」行であふれます。結果の行が出力されます。つまり、現在、スクリプトはresult値の取得を待機しておらず、取得したかのように繰り返し処理を続けているようです。

ここで何が間違っていますか?

4

5 に答える 5

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'
于 2013-05-27T20:41:14.173 に答える
2

ここにはいくつかの問題があります。最初は次のとおりです。

while q.full:

おそらく、関数を呼び出すつもりでした:

while q.full():

しかし、無限のキューがある (maxsize なしで作成した) ため、いっぱいになることはありません。したがって、その変更を行うと、scan() はまったく呼び出されません。

これを別の方法 (たとえば、 を使用) で修正すると仮定すると、 がキュー内のアイテムを均等に分割しないq.empty()場合はどうなるでしょうか? range(threads)たとえば、3 つのスレッドを使用し、ポート番号 1、2、3、および 4 を に配置するとしqます。q.get()外側の を通る最初のトリップで 3 回 (1、2、および 3 を取得)呼び出し、2 回目のトリップでもう一度 3 回呼び出しますが、whileそれにはもう 1 つの値しかありません。その後、誰かが a を実行するのを待ちます。4q.get()q.put()

つまり、ロジックを書き直す必要があります。

編集: s.closevsと同じ問題s.close()。他の人は、スレッドのプールの側面全体に対処しました。を使用する @Blender のバージョンmultiprocessingは、それを処理するため、はるかに簡単multiprocessingです。

于 2013-05-27T20:34:27.497 に答える
1

コードにはいくつかの問題があります。q.fullまず、関数である が偽になるまで while ループが続きます。しかし実際には、メイン スレッドでループする必要はありません。

ワーカー スレッドごとに 1 つずつ、キューの最後にセンチネル値を追加します。ワーカー スレッドがセンチネルを取得すると、その処理ループを終了します。この方法では、スレッドをデーモン化する必要はありません。

したがって、コードは次のようになります。

  • ポートをキューに入れる
  • センチネルをキューに入れる
  • 必要な数のスレッドを開始し、キューからポートを取得して処理し、結果を別のキューに入れます
  • t.join()スレッドが終了するのを待ち、ワーカーを呼び出します
  • 結果を使用する
于 2013-05-27T20:38:48.617 に答える
0

スレッド数の範囲内の数値を反復してスレッドを実行するだけでは、必要なスレッド数を維持できないことを知っておく必要があります。4回ループし、4つのスレッドを作成し、再びループして別の同じループに入り、それらの4つがタスクを完了したことを確認せずに別の4つを作成するため、印刷物をスキャン機能に入れると大量のメッセージが表示されます。

while 本体セクションの最後で子が終了するまで待つ必要があります。

おもう:

threading.wait()

ことを行います。

于 2013-05-27T20:34:08.420 に答える
-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()
于 2014-09-04T01:07:08.613 に答える