我是Python3.5和Async的新手,除了在Python 2.7中少量使用Twisted之外。我将其构建为一个更大的应用程序,我需要一小部分而不是单片框架来执行TCP端口扫描。
import asyncio
from random import SystemRandom
def run(task, *, loop=None):
if loop is None:
loop = asyncio.get_event_loop()
return loop.run_until_complete(asyncio.ensure_future(task, loop=loop))
async def scanner(ip, port, loop=None):
fut = asyncio.open_connection(ip, port, loop=loop)
try:
reader, writer = await asyncio.wait_for(fut, timeout=0.5) # This is where it is blocking?
print("{}:{} Connected".format(ip, port))
except asyncio.TimeoutError:
pass
def scan(ips, ports, randomize=False):
if randomize:
rdev = SystemRandom()
ips = rdev.shuffle(ips)
ports = rdev.shuffle(ports)
for port in ports:
for ips in ips:
run(scanner(ip, port))
ips = ["192.168.0.{}".format(i) for i in range(1, 255)]
ports = [22, 80, 443, 8080]
scan(ips, ports)
只要单个线程需要,这仍然需要。如何将其转换为异步TCP扫描程序?
答案 0 :(得分:2)
run_until_complete
正在阻塞,执行在那里停止并等待直到一次扫描结束,然后是下一次扫描......
您应安排所有(或部分)任务,并使用wait
等待所有任务。
import asyncio
from random import SystemRandom
def run(tasks, *, loop=None):
if loop is None:
loop = asyncio.get_event_loop()
# waiting for all tasks
return loop.run_until_complete(asyncio.wait(tasks))
async def scanner(ip, port, loop=None):
fut = asyncio.open_connection(ip, port, loop=loop)
try:
reader, writer = await asyncio.wait_for(fut, timeout=0.5) # This is where it is blocking?
print("{}:{} Connected".format(ip, port))
except asyncio.TimeoutError:
pass
# handle connection refused and bunch of others
except Exception as exc:
print('Error {}:{} {}'.format(ip, port, exc))
def scan(ips, ports, randomize=False):
loop = asyncio.get_event_loop()
if randomize:
rdev = SystemRandom()
ips = rdev.shuffle(ips)
ports = rdev.shuffle(ports)
# let's pass list of task, not only one
run([scanner(ip, port) for port in ports for ip in ips])
ips = ["192.168.0.{}".format(i) for i in range(1, 255)]
ports = [22, 80, 443, 8080]
scan(ips, ports)
我还添加了except
块来捕获其余的异常,包括拒绝最常见的连接。