流动python - 写port扫描仪和各种并发尝试(多线程/多进程/gevent/futures)

port扫描仪的原理非常easy。没有什么比操作更socket,能够connect它认为,port打开。

import socket
def scan(port):
    s = socket.socket()
    if s.connect_ex(('localhost', port)) == 0:
        print port, 'open'
    s.close()
if __name__ == '__main__':
    map(scan,range(1,65536))

这样一个最简单的端口扫描器出来了。

等等喂,半天都没反应,那是由于socket是堵塞的,每次连接要等非常久才超时。

我们自己给它加上的超时。

s.settimeout(0.1)

再跑一遍,感觉快多了。

多线程版本号

import socket
import threading
def scan(port):
    s = socket.socket()
    s.settimeout(0.1)
    if s.connect_ex(('localhost', port)) == 0:
        print port, 'open'
    s.close()

if __name__ == '__main__':
    threads = [threading.Thread(target=scan, args=(i,)) for i in xrange(1,65536)]
    map(lambda x:x.start(),threads)

执行一下,哇,好快,快到抛出错误了。thread.error: can‘t start new thread。

想一下,这个进程开启了65535个线程,有两种可能。一种是超过最大线程数了,一种是超过最大socket句柄数了。在linux能够通过ulimit来改动。

假设不改动最大限制,怎么用多线程不报错呢?

加个queue,变成生产者-消费者模式,开固定线程。

多线程+队列版本号

import socket
import threading
from Queue import Queue
def scan(port):
    s = socket.socket()
    s.settimeout(0.1)
    if s.connect_ex(('localhost', port)) == 0:
        print port, 'open'
    s.close()

def worker():
    while not q.empty():
        port = q.get()
        try:
            scan(port)
        finally:
            q.task_done()

if __name__ == '__main__':
    q = Queue()
    map(q.put,xrange(1,65535))
    threads = [threading.Thread(target=worker) for i in xrange(500)]
    map(lambda x:x.start(),threads)
    q.join()

这里开500个线程,不停的从队列取任务来做。

multiprocessing+队列版本号

总不能开65535个进程吧?还是用生产者消费者模式

import multiprocessing
def scan(port):
    s = socket.socket()
    s.settimeout(0.1)
    if s.connect_ex(('localhost', port)) == 0:
        print port, 'open'
    s.close()

def worker(q):
    while not q.empty():
        port = q.get()
        try:
            scan(port)
        finally:
            q.task_done()

if __name__ == '__main__':
    q = multiprocessing.JoinableQueue()
    map(q.put,xrange(1,65535))
    jobs = [multiprocessing.Process(target=worker, args=(q,)) for i in xrange(100)]
    map(lambda x:x.start(),jobs)

注意这里把队列作为一个參数传入到worker中去,由于是process safe的queue。不然会报错。

还实用的是JoinableQueue()。顾名思义就是能够join()的。

gevent的spawn版本号

from gevent import monkey; monkey.patch_all();
import gevent
import socket
...
if __name__ == '__main__':
    threads = [gevent.spawn(scan, i) for i in xrange(1,65536)]
    gevent.joinall(threads)

注意monkey patch必须在被patch的东西之前import,不然会Exception KeyError.比方不能先import threading,再monkey patch.

gevent的Pool版本号

from gevent import monkey; monkey.patch_all();
import socket
from gevent.pool import Pool
...
if __name__ == '__main__':
    pool = Pool(500)
    pool.map(scan,xrange(1,65536))
    pool.join()

concurrent.futures版本号

import socket
from Queue import Queue
from concurrent.futures import ThreadPoolExecutor
...
if __name__ == '__main__':
    q = Queue()
    map(q.put,xrange(1,65536))
    with ThreadPoolExecutor(max_workers=500) as executor:
        for i in range(500):
            executor.submit(worker,q)

版权声明:本文博客原创文章。博客,未经同意,不得转载。

时间: 2024-10-07 05:28:37

流动python - 写port扫描仪和各种并发尝试(多线程/多进程/gevent/futures)的相关文章

Python多线程多进程那些事儿看这篇就够了~~

自己以前也写过多线程,发现都是零零碎碎,这篇写写详细点,填一下GIL和Python多线程多进程的坑~ 总结下GIL的坑和python多线程多进程分别应用场景(IO密集.计算密集)以及具体实现的代码模块. 目录   0x01 进程 and 线程 and “GIL” 0x02 python多线程&&线程锁&&threading类 0x03 python队列代码实现 0x04 python之线程池实现 0x05 python多进程并行实现 0x01 进程 and 线程 and “

python写的端口扫描脚本

今天看到群里哥们发了一个需求,如下: "如何批量检测一批主机的端口,是否存在,端口都是对外的",感觉不难,就用py写了个小脚本,有问题的地方,还望大家指出,谢谢! #!/usr/bin/env python import socket file = "C:\Users\Administrator\py_demo\ip.txt" port = 80 a = open(file, 'r') b = a.readlines() a.close() for i in b:

用python写MapReduce函数

尽管Hadoop框架是用java写的,但是Hadoop程序不限于java,可以用python.C++.ruby等.本例子中直接用python写一个MapReduce实例,而不是用Jython把python代码转化成jar文件. 例子的目的是统计输入文件的单词的词频. 输入:文本文件 输出:文本(每行包括单词和单词的词频,两者之间用'\t'隔开) 1. Python MapReduce 代码 使用python写MapReduce的"诀窍"是利用Hadoop流的API,通过STDIN(标准

用python写一个专业的传参脚本

问:linux系统命令如ls,它有几十个参数,可带一个或多个参数,可不分先后,用起来是非常的专业.但是自己写的传参脚本,一般只传一个参数,如果传多个,也是固定的顺序,那么如何用python写出更专业的传参脚本呢? 答:使用python自带的getopt模块. 1.语法: import getopt getopt.getopt(args,shortopts, longopts=[]) #函数示例:getopt.getopt(sys.argv[1:],'u:p:P:h',["username=&qu

python并发编程&多线程(一)

本篇理论居多,实际操作见:  python并发编程&多线程(二) 一 什么是线程 在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程 线程顾名思义,就是一条流水线工作的过程,一条流水线必须属于一个车间,一个车间的工作过程是一个进程 车间负责把资源整合到一起,是一个资源单位,而一个车间内至少有一个流水线 流水线的工作需要电源,电源就相当于cpu 所以,进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合),而线程才是cpu上的执行单位. 多线程(即多个控制线程)的概念

十行代码--用python写一个USB病毒 (知乎 DeepWeaver)

昨天在上厕所的时候突发奇想,当你把usb插进去的时候,能不能自动执行usb上的程序.查了一下,发现只有windows上可以,具体的大家也可以搜索(搜索关键词usb autorun)到.但是,如果我想,比如,当一个usb插入时,在后台自动把usb里的重要文件神不知鬼不觉地拷贝到本地或者上传到某个服务器,就需要特殊的软件辅助. 于是我心想,能不能用python写一个程序,让它在后台运行.每当有u盘插入的时候,就自动拷贝其中重要文件. 如何判断U盘的插入与否? 首先我们打开电脑终端,进入/Volume

快速掌握用python写并行程序

目录 一.大数据时代的现状 二.面对挑战的方法 2.1 并行计算 2.2 改用GPU处理计算密集型程序 3.3 分布式计算 三.用python写并行程序 3.1 进程与线程 3.2 全局解释器锁GIL: 3.3 multiprocessing 四.multiprocessing实战 总结 小子今天想来谈谈"并行计算",作为一个非科班人员,我为什么去捣鼓这么一个在科班里也比较专业的问题了.这就要说下我前几天做的一个作业了,当时我用python写了个程序,结果运行了一天,这个速度可让我愁了

用Python写网络爬虫(高清版)PDF

用Python写网络爬虫(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1kdRFAEuze-A9ToWVXHoCXw 提取码:8ib1 复制这段内容后打开百度网盘手机App,操作更方便哦 内容简介  · · · · · · 作为一种便捷地收集网上信息并从中抽取出可用信息的方式,网络爬虫技术变得越来越有用.使用Python这样的简单编程语言,你可以使用少量编程技能就可以爬取复杂的网站. <用Python写网络爬虫>作为使用Python来爬取网络数据的杰出指南,

python 学习_第四模块 并发编程(多线程)

python 学习_第四模块 并发编程(多线程) 1  开启线程方式 from threading import Thread import time def say(name): time.sleep(2) print("%s hello"%name) if __name__ =="__main__": t = Thread(target=say,args=("alex",)) t.start() print("主线程")