2018-12-04-Python全栈开发-day95-IO多路复用

import socket
import select


class MakeRequest:
    '''用来将socket和url信息以及回调函数进行封装'''

    def __init__(self, sock, host, callback):
        self.sock = sock
        self.host = host
        self.callback = callback

    def fileno(self):
        return self.sock.fileno()  # 可以放到select中


class AsyncRequest:
    '''根据发来的host进行访问'''

    def __init__(self):  # 用来盛放socket对象
        self.wlist = []  # 监听w
        self.rlist = []  # 监听r

    def add_socket(self, host, callback):
        '''根据host生成socket'''
        try:
            sock = socket.socket()
            sock.setblocking(0)  # 设置为非阻塞
            sock.connect((host, 80))  # 对主机进行连接,默认为80端口
        except BlockingIOError as e:
            pass
        request = MakeRequest(sock, host, callback)  # 将sock以及对应的封装在一起
        self.wlist.append(request)
        self.rlist.append(request)
        # 检测是否连接上了

    def run(self):
        '''运行socket'''
        while 1:
            r, w, e = select.select(self.rlist, self.wlist,self.rlist, 0.05)

            for w in self.wlist:
                '''对socket对象进行监听,如果w有动静,则说明连接上了'''
                print(w.host, '已经连接上')
                info = "GET / HTTP/1.0\r\nHost:%s\r\n\r\n" % (w.host)

                w.sock.send(bytes(info, encoding='utf-8'), )

                self.wlist.remove(w)
            for r in self.rlist:  # 用来接收数据
                recv = bytes()
                while 1:
                    try:

                        chunk = r.sock.recv(8096)
                        recv += chunk
                    except Exception as e:
                        break
                print(recv)
                r.callback(recv)
                r.sock.close()
                self.rlist.remove(r)
            if len(self.rlist) == 0:  # 所有的socket都处理完成
                break


# 准备接口
def f1(data):
    print('f1')


def f2(data):
    print('f2')


def f3(data):
    print('f3')


'''不同的url可以有不同回调函数'''
url_list = [
    {'host': 'www.baidu.com', 'callback': f1},
    {'host': 'www.google.com', 'callback': f2},
    {'host': 'www.cnblogs.com', 'callback': f3},

]
# 处理回调函数的时候,可以进行再次封装,将url和socket封装在一块
req = AsyncRequest()
for url in url_list:
    # 先对urllist进行格式改变
    req.add_socket(url['host'], url['callback'])

req.run()

 

转载于:https://www.cnblogs.com/hai125698/p/10117103.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值