协程编程实战

一、协程技术
1.协程的概述
在这里插入图片描述

2.协程的优缺点
优点:
在这里插入图片描述
在这里插入图片描述
缺点:
在这里插入图片描述

3.基本用法
在这里插入图片描述

# time是默认阻塞
# 解决:能否修改非阻塞方式,在操作io的时候,立马切换到其他的协程运行!
# from gevent import monkey
# monkey.patch_all()  # 解决:能否修改非阻塞方式,在操作io的时候,立马切换到其他的协程运行!
# import time
# import gevent


def f1():
    for one in range(5):
        print(f'f1 在运行---{one}')
        time.sleep(1)


def f2():
    for one in range(5):
        print(f'f2 在运行---{one}')
        time.sleep(1)


# 创建协程对象
# t1 = gevent.spawn(f1)
# t2 = gevent.spawn(f2)

# 运行
# gevent.joinall([t1, t2])

# ---------------------------------------
# 实例使用:tcp请求  socket;其他请求  requests

# ---------------------------------------
# time是默认阻塞
# 解决:能否修改非阻塞方式,在操作io的时候,立马切换到其他的协程运行!
from gevent import monkey

monkey.patch_all()  # 解决:能否修改非阻塞方式,在操作io的时候,立马切换到其他的协程运行!
import time
import gevent
import requests
from datetime import datetime


def get_data(url):
    print(f'{datetime.now()}-开始-GET-开始获取数据>>>')
    resp = requests.get(url)
    print(f'{datetime.now()}-结束-GET-开始获取数据>>>')


# get_data("http://vip.ytesting.com/")
# get_data("http://www.songqinnet.com/")

# 创建
gevent.joinall(
    [gevent.spawn(get_data, "http://vip.ytesting.com/"),
     gevent.spawn(get_data, "http://www.songqinnet.com/")]
)
print('执行结束')

二、协程实战(端口扫描)

# -----------------------------v5.0---------------------------------
'''
测试反馈:
    1.是否可以自动识别ip或者域名---在输入的时候判断!
    2.如果全扫描--发现很慢----------因为单线程跑,效率低---建议使用多线程、协程!
    3.如果出现扫描结果不一样,可以使用取并集  set1 | set2 ----一个思路
优化方案:周期
    1- 多线程/协程---并发操作
    2- 做ip有效值判断
    8.136.98.37
    31990-32000
    47.96.181.17
'''
# ------------------------------------------------------------------
import socket
import re


# 1- ip的有效判断-re 0.0.0.0~255.255.255.255
def check_ip(ip):
    """
    :param ip:输入
    :return:是否符合规则
    """
    ip_address = re.compile(r'(([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])\.){3}([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])')
    if ip_address.match(ip) and len(ip) != 0:
        return True
    else:
        return False


def check_domain(hostname):
    """
    :param hostname:输入
    :return:是否符合规则
    """
    domainName = re.compile('[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?')
    if domainName.match(hostname) and len(hostname) != 0:
        return True
    else:
        return False


# 2- 直接使用ip-扫描
def scan_ip(ip):
    # 2- 使用ip判断函数--判断
    if check_ip(ip):
        # 进入扫描端口
        gevent_scan_port(ip)
    else:
        print('ip格式有误,请检查!')


# 3- 使用域名扫描
def domain_name_scan(domainName):
    # 2- 可做域名判断
    if 'http://' in domainName or 'https://' in domainName:
        domainName = domainName[domainName.find("://")+3:]  # 取前写后下标
        print("正在解析的域名>>>", domainName)
    # 2- 获取ip
    server_ip = socket.gethostname()
    print(f"该域名{domainName}的ip>>>{server_ip}")
    gevent_scan_port(server_ip)


# 导出文件
def export_file(info):
    fo = open("scanPort.txt", 'a', encoding='utf-8')
    fo.write(info)
    fo.close()


# 4- 端口扫描函数
def scan_port(ip, port):  # 分段
    # 访问成功是有返回值--是0
    # 使用ip 实现tcp连接
    sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sk.settimeout(0.5)
    try:
        conn = sk.connect_ex((ip, port))  # 有返回值('127.0.0.1', int型)
        if conn == 0:
            print(f'主机:{ip}, 端口:{port}已开放')
            export_file(f'主机:{ip}, 端口:{port}已开放\n')
    except:
        pass
    sk.close()


# 多线程-扫描
from gevent import monkey
monkey.patch_all()
import time
import gevent
import gevent.pool


def gevent_scan_port(ip):
    start_time = time.time()  # 开始计时
    g = gevent.pool.Pool(500)  # 限制协程的并发数量
    export_file(f'主机:{ip},开始扫描......\n')
    run_list = []  # 运行的协程
    for port in range(1, 65535+1):
        run_list.append(g.spawn(scan_port, ip, port))
    gevent.joinall(run_list)  # 运行完,主线程退出  阻塞
    end_time = time.time()
    print('端口扫描总共耗时>>>', end_time - start_time)
    export_file(f'主机:{ip},扫描结束......\n')


# 5- 主入口
def main():
    info = input('请选择ip或者域名>>>')
    # 2- 接收用户输入
    if check_ip(info):
        # ip扫描
        scan_ip(info)
    elif check_domain(info):
        # 域名扫描
        domain_name_scan(info)
    else:
        print('输入有误!')


if __name__ == '__main__':
    main()

扩展:
版本:V6.0
需求:
1、可以有操作的GUI页面
2、可以发送邮件:文件格式/字符串发送----安全

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

每 天 早 睡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值