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)

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

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

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

    自己以前也写过多线程,发现都是零零碎碎,这篇写写详细点,填一下GIL和Python多线程多进程的坑~ 总结下GIL的坑和python多线程多进程分别应用场景(IO密集.计算密集)以及具体实现的代码模块 ...

  2. 【Python】如何基于Python写一个TCP反向连接后门

    首发安全客 如何基于Python写一个TCP反向连接后门 https://www.anquanke.com/post/id/92401 0x0 介绍 在Linux系统做未授权测试,我们须准备一个安全的 ...

  3. 用Python写一个简单的Web框架

    一.概述 二.从demo_app开始 三.WSGI中的application 四.区分URL 五.重构 1.正则匹配URL 2.DRY 3.抽象出框架 六.参考 一.概述 在Python中,WSGI( ...

  4. 教你用python写:HDU刷题神器

    声明:本文以学习为目的,请不要影响他人正常判题 HDU刷题神器,早已被前辈们做出来了,不过没有见过用python写的.大一的时候见识了学长写这个,当时还是一脸懵逼,只知道这玩意儿好屌-.时隔一年,决定 ...

  5. python写的一个集合

    起因:原本打算用python写一个抢火车票的脚本.在那 期间遇见各种浏览器驱动失败的节奏....打算先缓一下 然后就去写集合了. 0x01 源码: # -*- coding:'utf-8' -*- # ...

  6. python多进程并发和多线程并发和协程

    为什么需要并发编程? 如果程序中包含I/O操作,程序会有很高的延迟,CPU会处于等待状态,这样会浪费系统资源,浪费时间 1.Python的并发编程分为多进程并发和多线程并发 多进程并发:运行多个独立的 ...

  7. Python 网站后台扫描脚本

    Python  网站后台扫描脚本 #!/usr/bin/python #coding=utf-8 import sys import urllib import time url = "ht ...

  8. 用python写MapReduce函数——以WordCount为例

    尽管Hadoop框架是用java写的,但是Hadoop程序不限于java,可以用python.C++.ruby等.本例子中直接用python写一个MapReduce实例,而不是用Jython把pyth ...

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

    昨天在上厕所的时候突发奇想,当你把usb插进去的时候,能不能自动执行usb上的程序.查了一下,发现只有windows上可以,具体的大家也可以搜索(搜索关键词usb autorun)到.但是,如果我想, ...

随机推荐

  1. Apache与Tomcat整合(转)

    一 Apache与Tomcat比较联系 apache支持静态页,tomcat支持动态的,比如servlet等. 一般使用apache+tomcat的话,apache只是作为一个转发,对jsp的处理是由 ...

  2. BootstrapQ 包Bootstrap tree,dialog等待

    官方网站:http://uikoo9.com/bootstrapQ why 事实上bootstrap已经非常好了,唯一的软肋就是js方面有些薄弱,对照easyui就知道了. 能够非常明显的知道boot ...

  3. 乐在其中设计模式(C#) - 模板方法模式(Template Method Pattern)

    原文:乐在其中设计模式(C#) - 模板方法模式(Template Method Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 模板方法模式(Template Method ...

  4. NFS 配置服务

    NFS 配置服务 北京市海淀区  张俊浩 一.NFS.即网络文件系统(Network File System,NFS).一种使用于分散式文件系统的协议,由升阳公司开发.于1984年向外发布.功能是通过 ...

  5. 解决visual studio空格变成很多点号的3种方法

    在用visual studio做网站时不知道按了什么快捷键,所有页面上的空格都变成了点号,就像下图那样. 要解决空格变点号的方法有两种:1.编辑->高级->查看空白2.Ctrl+E 然后按 ...

  6. hibernate它 10.many2many单向

    在前文hibernate之5.many2one单向提到多对多关系,表结构设计是基于中间表来实现, 以下以用户与角色(多对多)为例,在Hibernate是怎样操作的 表结构设计: 类图: CRUD; S ...

  7. hdu3572 任务分配/最大流量推论全流

    意甲冠军:将n分配的任务m机.到的每个任务需要的天数(如果没有持续的日常),并能做到在哪些天任务.询问是否有计划. 典型的任务(X)----日(Y)一半的最大流量,(因为这个任务是天之间的关系)处理器 ...

  8. Cocos2d-x Auto-batching 浅浅的”深入分析”

    Auto-batching是Cocos2d-x3.0新增的特性,目的是为了代替SpriteBatchNode,完毕渲染的批处理,提高绘制效率. 至于它有什么特点,能够看看官方文档,这里主要想探讨Aut ...

  9. UVa 10397 Connect the Campus

    最小生成树 Kruskal #include<cmath> #include<iostream> #include<cstdio> #include<algo ...

  10. js 执行一个字符串类型的函数

    两种方法,一种是加括号一种是加叹号,new Function()的方法没有成功. var a = "function(args){console.log(args)}" undef ...