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()