下面我将详细讲解“python多线程扫描端口(线程池)”的完整攻略。
线程池的概念
线程池是一种应对高并发、高频率任务的一种解决方案,它将线程复用起来,减少了创建、销毁线程的开销,从而提高了程序的效率。
当我们需要同时进行多个扫描时,就需要采用多线程的方式来进行。而线程池则是一种比较好用的多线程技术,它可以控制线程的数量,避免资源的浪费,让线程在需要时自动重用。
实现步骤
下面是实现“python多线程扫描端口(线程池)”所需要的步骤:
- 导入必要的库,例如
threading
和queue
等库。
import threading
import queue
- 定义扫描函数
定义一个扫描给定IP的端口的函数,可以通过socket库的connect_ex()方法来实现。
def scan_port(ip, port):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(1)
try:
conn = s.connect_ex((ip, port))
if conn == 0:
print('[+]%d open' % port)
s.close()
except:
pass
- 定义线程函数
定义一个线程函数work,实现从任务队列中获取任务并且执行,直到任务队列为空为止。
def work():
while True:
try:
ip, port = q.get(block=False)
scan_port(ip, port)
except queue.Empty:
break
- 定义主函数
在主函数中,将IP列表中所有的IP和需要扫描的所有端口添加到任务队列q中,然后创建多个线程来执行work函数,最后等待所有线程执行完成。
if __name__ == '__main__':
threads = []
q = queue.Queue()
for ip in ips:
for port in ports:
q.put((ip, port))
for i in range(10):
t = threading.Thread(target=work)
threads.append(t)
t.start()
for t in threads:
t.join()
在上述代码中,我们创建了10个线程,然后将所有待扫描的任务加入到任务队列q中,线程池中的每个线程都会从队列中获取一个任务并执行,直到队列为空。
- 示例一
下面是一个简单的示例,演示如何扫描一个IP地址段的80端口。
import queue
import threading
import socket
def scan_port(ip, port):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(1)
try:
conn = s.connect_ex((ip, port))
if conn == 0:
print('[+] %s:%d Open' % (ip, port))
s.close()
except:
pass
def work():
while True:
try:
ip, port = q.get(block=False)
scan_port(ip, port)
except queue.Empty:
break
if __name__ == '__main__':
threads = []
q = queue.Queue()
for i in range(1, 255):
q.put(('192.168.1.%d' % i, 80))
for i in range(10):
t = threading.Thread(target=work)
threads.append(t)
t.start()
for t in threads:
t.join()
在这个示例中,我们首先定义了扫描端口的函数scan_port()
,然后定义了线程函数work()
。在主函数中,我们将IP地址段1~254中的所有主机和80端口加入到任务队列q中,并创建10个线程来执行所有任务。
- 示例二
下面是一个稍微复杂一些的示例,它可以同时扫描多个端口和多个IP地址段。
import queue
import threading
import socket
def scan_port(ip, port):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(1)
try:
conn = s.connect_ex((ip, port))
if conn == 0:
print('[+] %s:%d Open' % (ip, port))
s.close()
except:
pass
def work():
while True:
try:
ip, port = q.get(block=False)
scan_port(ip, port)
except queue.Empty:
break
if __name__ == '__main__':
threads = []
q = queue.Queue()
ips = ['192.168.1.%d' % i for i in range(1, 51)]
ports = [21,22,23,25,53,66,80,81,135,139,443,445,1433,1521,3306,3389,5432,5900,5901,6379,7001,8000,8080,8090,8888]
for ip in ips:
for port in ports:
q.put((ip, port))
for i in range(10):
t = threading.Thread(target=work)
threads.append(t)
t.start()
for t in threads:
t.join()
在这个示例中,我们首先定义了两个列表nd的所有主机和80端口加入到任务队列q中,并创建10个线程来执行所有任务。最终输出所有开放的端口。
这就是“python多线程扫描端口(线程池)”的完整攻略了,希望对你有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python多线程扫描端口(线程池) - Python技术站