Use non-blocking io completed http request

# coding: utf-8
# 1. epoll 不代表一定比select好
# 在并发高的情况下, 连接活跃度不高, epoll比select好
# 并发性不高, 同时连接很活跃, select比epoll好

# 通过非阻塞io发起http请求


import socket
from urllib.parse import urlparse


# 使用非阻塞请求完成http请求
def get_url(url):
    # 通过socket请求html
    url = urlparse(url)
    host = url.netloc
    path = url.path
    if path == '':
        path = '/'

    # 建立socket连接
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client.setblocking(False)  # 非阻塞 不用等待返回继续执行
    try:
        # connect 需要判断是否连接完成负责会发生BlockingIOError异常
        client.connect((host, 80))
    except BlockingIOError:
        pass

    # 如果connect连接捕获异常任然执行send消息同样会抛出异常,该异常为OSError  应该不停尝试 如果成功则跳出循环
    while 1:
        try:
            client.send('GET {} HTTP/1.1\r\nHOST:{}\r\nConnection:close\r\n\r\n'.format(path, host).encode('utf8'))
            break
        except OSError:
            pass

    data = b''
    while 1:
        # 如果没有连接正常 recv同样会报错BlockingIOError
        try:
            d = client.recv(1024)
        except BlockingIOError as e:
            continue
        if d:
            data += d
        else:
            break
    data = data.decode('utf8')
    print(data)
    client.close()


if __name__ == '__main__':
    get_url('http://www.baidu.com')

Guess you like

Origin blog.csdn.net/weixin_33896069/article/details/91000564