流动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)
版权声明:本文博客原创文章。博客,未经同意,不得转载。
流动python - 写port扫描仪和各种并发尝试(多线程/多进程/gevent/futures)的更多相关文章
- Python多线程多进程那些事儿看这篇就够了~~
自己以前也写过多线程,发现都是零零碎碎,这篇写写详细点,填一下GIL和Python多线程多进程的坑~ 总结下GIL的坑和python多线程多进程分别应用场景(IO密集.计算密集)以及具体实现的代码模块 ...
- 【Python】如何基于Python写一个TCP反向连接后门
首发安全客 如何基于Python写一个TCP反向连接后门 https://www.anquanke.com/post/id/92401 0x0 介绍 在Linux系统做未授权测试,我们须准备一个安全的 ...
- 用Python写一个简单的Web框架
一.概述 二.从demo_app开始 三.WSGI中的application 四.区分URL 五.重构 1.正则匹配URL 2.DRY 3.抽象出框架 六.参考 一.概述 在Python中,WSGI( ...
- 教你用python写:HDU刷题神器
声明:本文以学习为目的,请不要影响他人正常判题 HDU刷题神器,早已被前辈们做出来了,不过没有见过用python写的.大一的时候见识了学长写这个,当时还是一脸懵逼,只知道这玩意儿好屌-.时隔一年,决定 ...
- python写的一个集合
起因:原本打算用python写一个抢火车票的脚本.在那 期间遇见各种浏览器驱动失败的节奏....打算先缓一下 然后就去写集合了. 0x01 源码: # -*- coding:'utf-8' -*- # ...
- python多进程并发和多线程并发和协程
为什么需要并发编程? 如果程序中包含I/O操作,程序会有很高的延迟,CPU会处于等待状态,这样会浪费系统资源,浪费时间 1.Python的并发编程分为多进程并发和多线程并发 多进程并发:运行多个独立的 ...
- Python 网站后台扫描脚本
Python 网站后台扫描脚本 #!/usr/bin/python #coding=utf-8 import sys import urllib import time url = "ht ...
- 用python写MapReduce函数——以WordCount为例
尽管Hadoop框架是用java写的,但是Hadoop程序不限于java,可以用python.C++.ruby等.本例子中直接用python写一个MapReduce实例,而不是用Jython把pyth ...
- 十行代码--用python写一个USB病毒 (知乎 DeepWeaver)
昨天在上厕所的时候突发奇想,当你把usb插进去的时候,能不能自动执行usb上的程序.查了一下,发现只有windows上可以,具体的大家也可以搜索(搜索关键词usb autorun)到.但是,如果我想, ...
随机推荐
- 【Android进阶】Android面试题目整理与讲解(二)
1. ArrayList,Vector, LinkedList 的存储性能和特性 ArrayList 和 Vector 都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们 ...
- OpenStack Dashboard
OpenStackDashboard 为管理员和普通用户提供了一个图形化管理界面.用户能够通过该界面訪问.分配或者自己主动化分配基于云的资源.可扩展的设计使得与第三方产品和服务融合变得非常easy,比 ...
- 使用ZeroMQ(clrzmq)实现异步通信
ZeroMQ是对Socket的封装,通过组合多种类型的结点可以实现复杂的网络通信模式.而且ZeroMQ设计简单,可以有多种平台实现,对于跨平台项目是一个福音. clrzmq是ZeroMQ的C#语言的实 ...
- 使用Intellij Idea生成可执行文件jar,开关exe文件步骤
确保其Java代码是没有问题的,在IDEA常执行的,然后.按以下步骤: 步骤一:打开File -> Project Structure -> Artifacts,例如以下图 步骤二:点击& ...
- 【Linux探索之旅】第一部分第五课:Unity桌面,人生若只如初见
内容简介 1.第一部分第五课:Unity桌面,人生若只如初见 2.第一部分第六课预告:Linux如何安装在虚拟机中 Unity桌面,人生若只如初见 不容易啊,经过了前几课的学习,我们认识了Linux是 ...
- GUI (图形界面)知识点
一:组件知识点 JTextField: 作用: 定义文本域,只支持单行输入. 使用: 定义文本域: JTextField jtf=new JTextField ...
- ORACLE—002:Create创作型
--用于工作的积累SQL ORACLE另外还有的类型.储过程.函数等的输入输入出. 以下看下创建. 使用方法 CREATE OR REPLACE TYPE 类型名称 AS OBJECT( 字段1 ...
- 华为-on演习--身高找到最好的二人
称号: 从5个人选择2作为个人礼仪器.中的每个个体的身高的范围160-190,要求2各高度差值至少(假设差异值同样的事情,他们中最高的选择),输出的两个人的身高升序. Smple input:161 ...
- 基于RDP开源许可rdesktop基本介绍
**************************************************************************************************** ...
- 我学的是设计模式的视频教程——辛格尔顿,生成器VS工厂方法
课程视频 单例模式 建造者VS工厂方法 课程笔记 课程笔记 课程代码 课程代码 新课程火热报名中 课程介绍 版权声明:本文博客原创文章,博客, ...