• 基于socket实现http请求


    异步非阻塞模块原理

    # 基于socket实现http请求
    import socket
    # 多路IO复用模块
    import select
    
    
    socket_list= []
    url_list = ["http://www.baidu.com", ...]
    for url in url_list:
        sk = socket.socket()
        # 设置非阻塞模式
        sk.setblocking(False)
        try:
            sk.connect((url, 80))
        except BlockingIOError as e:
            print(e)
        # 为每个url请求都创建一个socket对象并把它放到一个列表里
        socket_list.append(sk)
    
    
    # 事件循环
    # tornado/twisted事件循环的原理就是通过这种方式来实现的
    while True:
        # 监测socket是否连接成功了
        # 监测socket是否可以进行接受数据了
        r, w, e = select.select(socket_list, socket_list, [], 0.05)
        for obj in w:
            obj.send("GET / HTTP1.1
    host:...")
        for obj in r:
            response = obj.recv(4096)
            print(response)

    自定制一个基于socket实现的异步非阻塞模块

    import socket
    import select
    import uuid
    
    
    # 定义一个Request类 对socket对象进行二次封装
    class Request(object):
        def __init__(self, sock, info):
            self.sock = sock
            self.info = info
    
        def fileno(self):
            return self.sock.fileno()
    
    
    class Lou(object):
    
        def __init__(self):
            self.sock_list = []
            self.conn_list = []
    
        def add_request(self, req_info):
            sk = socket.socket()
            sk.setblocking(False)
            try:
                sk.connect((req_info['host'], req_info['port']))
            except BlockingIOError as e:
                pass
            obj = Request(sk, req_info)
            self.conn_list.append(obj)
            self.sock_list.append(obj)
    
        def run(self):
            while True:
                # 只要列表中的对象有fileno方法就可以作为select的参数
                r, w, e = select.select(self.sock_list, self.conn_list, [], 0.05)
                for obj in w:
                    data = "GET %s HTTP/1.1
    host:%s
    
    " % (obj.info["path"], obj.info["host"])
                    obj.sock.send(data.encode("utf-8"))
                    self.conn_list.remove(obj)
                for obj in r:
                    response = obj.sock.recv(8192)
                    print(obj.info["host"], response)
                    self.sock_list.remove(obj)
                    obj.info["callback"](response)
                if not self.sock_list:
                    break
    
    
    def done(response):
        filename = uuid.uuid4()
        with open("%s.html"%filename, "wb") as f:
            f.write(response)
    
    
    url_list = [
        {"host": "www.baidu.com", "port": 80, "path": "/", "callback": done},
        {"host": "www.cnblogs.com", "port": 80, "path": "/", "callback": done},
        {"host": "www.bing.com", "port": 80, "path": "/", "callback": done},
    ]
    
    l = Lou()
    for req_info in url_list:
        l.add_request(req_info)
    
    l.run()
  • 相关阅读:
    Hadoop学习------Hadoop安装方式之(一):单机部署
    Linux系统上安装、卸载JAVA、TOMCAT的方法
    在Linux系统上安装Oracle数据库
    C:Program Files (x86)MSBuild14.0inMicrosoft.Common.CurrentVersion.targets(4714,5): error MSB30...
    软件设计,数据库结构设计,设计思想
    面试题 SqlServer知识
    @Ajax.ActionLink跳转页面的问题解决方案 MVC Ajax不支持问题
    .net机试题总结
    .Net机试题——编写一个BS架构的多层表结构的信息管理模块
    C# 不同类型对象同名属性赋值
  • 原文地址:https://www.cnblogs.com/louyifei0824/p/9873841.html
Copyright © 2020-2023  润新知