import socket
from selectors import DefaultSelector, EVENT_READ, EVENT_WRITE

# 会根据当前的操作系统选择一个合适的文件描述符,Linux下是epoll,Windows下则是select
selector = DefaultSelector()

class Fetcher:

    def __init__(self, host):
        self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.client.setblocking(False)  # 设置非阻塞socket
        self.host = host

    def get_url(self):
        try:
            self.client.connect((self.host, 80))
        except BlockingIOError:
            # 也可以做一些其他的事
            pass

        # 将socket注册一个事件,self.client.fileno()是当前socket的文件描述符,
        # EVENT_WRITE表示可写,因为我们连接建立好之后要send一个请求(相当于写数据),所以等待一个可写状态
        # 并且绑定一个回调函数,如果连接建立好了,说明可以写了,那么就调用相应的回调函数
        selector.register(self.client.fileno(), EVENT_WRITE, self.send_request)

    def send_request(self, key):
        # 这里的参数key指的便是调用当前函数的socket
        # 调用了之后,我们就不再监视了,因此要取消注册,key.fd指的便是key(当前socket)的fd(file descriptor)
        selector.unregister(key.fd)
        self.client.send("GET {} HTTP/1.1\r\nHost:{}\r\nConnection:close\r\n\r\n".format("/", self.host).encode("utf-8"))
        # 这时候便将我们的请求发出去了,但是我们还要继续注册新的socket
        # EVENT_READ指的是可读,我们发送一个请求之后要等待服务器返回数据(相当于读数据),所以等待一个可读状态
        # 当满足可读状态,那么调用相应的回调函数读取数据
        selector.register(self.client.fileno(), EVENT_READ, self.read_data)

    def read_data(self, key):
        data = b""
        recv = self.client.recv(1024)
        if recv:
            data += recv
        else:
            # 值获取完毕,那么取消注册
            selector.unregister(key.fd)

        print(str(data, encoding="utf-8", errors="ignore"))

def loop_forever():
    # 事件循环,为什么需要事件循环
    # 因为我们上面绑定的回调函数没办法自动调用,所以我们必须创建一个事件循环,不断地从里面取出满足状态的socket
    while 1:
        ready = selector.select()
        for key, mask in ready:
            # key.data就是我们注册的回调的函数
            call_back = key.data
            # 将key也就是相应的socket主动传进去
            call_back(key)

if __name__ == '__main__':
    fetcher = Fetcher("www.baidu.com")
    fetcher.get_url()
    loop_forever()

  可以看到,这种编程模式将我们的代码割的四分五裂。因此程序员更喜欢使用同步的方式编写异步代码

python--selectors的更多相关文章

  1. Python/ selectors模块及队列

    Python/selectors模块及队列 selectors模块是可以实现IO多路复用机制: 它具有根据平台选出最佳的IO多路机制,比如在win的系统上他默认的是select模式而在linux上它默 ...

  2. Python - selectors 模块

    selectors 模块 它的功能与 linux 的 epoll,还是 select 模块,  poll 等类似: 实现高效的 I/O multiplexing ,  常用于非阻塞的 socket  ...

  3. Python selectors实现socket并发

    selectors模块 此模块允许基于选择模块原语构建高级别和高效的I / O多路复用. 鼓励用户使用此模块,除非他们想要精确控制使用的os级别的原语. 注:selectors也是包装了select高 ...

  4. python selectors模块实现 IO多路复用机制的上传下载

    import selectorsimport socketimport os,time BASE_DIR = os.path.dirname(os.path.abspath(__file__))''' ...

  5. Day15 - Python基础15 模块学习-selectors

    本节内容 1:Python/selectors模块 2:selsect实例 1:Python/selectors模块及队列  selectors模块是可以实现IO多路复用机制: 它具有根据平台选出最佳 ...

  6. Python 运维之路

    第一章:Python基础知识 1.Python 变量了解 .Python 二进制 .Python 字符编码 4.Python if条件判断 5.Python while循环 6.Python for循 ...

  7. (转)python异步编程--回调模型(selectors模块)

    原文:https://www.cnblogs.com/zzzlw/p/9384308.html#top 目录 0. 参考地址 1. 前言 2. 核心类 3. SelectSelector核心函数代码分 ...

  8. python 利用selectors实现异步I/O

    它的功能与linux的epoll,还是select模块,poll等类似:实现高效的I/O multiplexing,  常用于非阻塞的socket的编程中: 简单介绍一下这个模块,更多内容查看 pyt ...

  9. python异步编程--回调模型(selectors模块)

    目录 0. 参考地址 1. 前言 2. 核心类 3. SelectSelector核心函数代码分析 3.1 注册 3.2 注销 3.3 查询 4. 别名 5. 总结 6. 代码报错问题 1. 文件描述 ...

  10. python 全栈开发,Day44(IO模型介绍,阻塞IO,非阻塞IO,多路复用IO,异步IO,IO模型比较分析,selectors模块,垃圾回收机制)

    昨日内容回顾 协程实际上是一个线程,执行了多个任务,遇到IO就切换 切换,可以使用yield,greenlet 遇到IO gevent: 检测到IO,能够使用greenlet实现自动切换,规避了IO阻 ...

随机推荐

  1. LeetCode 33——搜索旋转排序数组

    1. 题目 2. 解答 2.1. 方法一 直接进行二分查找,在判断查找方向的时候详细分类. 当 nums[mid] < target 时, 若 nums[left] <= nums[mid ...

  2. PHP中的6种加密方式

    PHP中的6种加密方式 1. MD5加密 string md5 ( string $str [, bool $raw_output = false ] ) 参数 str  --  原始字符串. raw ...

  3. scrapy学习-爬取天天基金网基金列表

    目录 描述 环境描述 步骤记录 创建scrapy项目 设置在pycharm下运行scrapy项目 分析如何获取数据 编写代码 step 1:设置item step 2:编写spider step 3: ...

  4. lintcode-95-验证二叉查找树

    95-验证二叉查找树 给定一个二叉树,判断它是否是合法的二叉查找树(BST) 一棵BST定义为: 节点的左子树中的值要严格小于该节点的值. 节点的右子树中的值要严格大于该节点的值. 左右子树也必须是二 ...

  5. BZOJ4361 isn(动态规划+树状数组+容斥原理)

    首先dp出长度为i的不下降子序列个数,显然这可以树状数组做到O(n2logn). 考虑最后剩下的序列是什么,如果不管是否合法只是将序列删至只剩i个数,那么方案数显然是f[i]*(n-i)!.如果不合法 ...

  6. 处理WebService asmx的经验

    项目的需求,需要和一个.net系统进行数据交换,合作方提供了一个WebService接口.这个与一般的PHP POST或GET传值再查库拿数据的思路有点不一样,需要用到SOAP模块,处理方法也很简单, ...

  7. Faster R-CNN教程

    Faster R-CNN教程 最后更新日期:2016年4月29日 本教程主要基于python版本的faster R-CNN,因为python layer的使用,这个版本会比matlab的版本速度慢10 ...

  8. [bzoj 3224]手写treap

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3224 bzoj不能用time(0),看到这个博客才知道,我也RE了好几发…… #inclu ...

  9. [poj 2796]单调栈

    题目链接:http://poj.org/problem?id=2796 单调栈可以O(n)得到以每个位置为最小值,向左右最多扩展到哪里. #include<cstdio> #include ...

  10. TOM的show_space

    show_space查看对像数据块的空闲情况 CREATE OR REPLACE PROCEDURE show_space(p_segname IN VARCHAR2, p_owner IN VARC ...