阻塞IO
'''
网络IO
阻塞io
非阻塞io
多路复用io
异步io
'''
import time
from threading import Thread0
import socket
def server():
server = socket.socket()
server.bind(("127.0.0.1", 8080))
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
server.listen(4)
while True:
conn, (ip, addr) = server.accept()
while True:
data = conn.recv(1024)
if len(data) == 0: break
conn.send(data.upper())
conn.close()
def client():
client = socket.socket()
client.connect(("127.0.0.1", 8080))
count = 0
while True:
data = "Hello world"
b_data = data.encode("utf-8")
count += len(b_data)
print("count is ", count)
client.send(b_data)
data = client.recv(1024)
print(data.decode("utf-8"))
if __name__ == '__main__':
Thread(target=server).start()
Thread(target=client).start()
非阻塞IO
非阻塞IO由于一直循环,因此如果没有数据连接也会导致占用非常高的CPU。
import time
from threading import Thread0
import socket
def server():
server = socket.socket()
server.bind(("127.0.0.1", 8080))
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
server.listen(4)
# 设置为非阻塞,默认为True
server.setblocking(False)
while True:
try:
conn, (ip, addr) = server.accept()
except BlockingIOError as e:
print(e)
while True:
data = conn.recv(1024)
if len(data) == 0: break
conn.send(data.upper())
conn.close()
def client():
client = socket.socket()
client.connect(("127.0.0.1", 8080))
count = 0
while True:
data = "Hello world"
b_data = data.encode("utf-8")
count += len(b_data)
print("count is ", count)
client.send(b_data)
data = client.recv(1024)
print(data.decode("utf-8"))
if __name__ == '__main__':
Thread(target=server).start()
Thread(target=client).start()
多路复用
select windows和linux都有
poll机制 只有Linux有, poll和select都可以监听多个对象,但是poll监管的数量更多。
epoll机制。只有Linux有。 每个监听对象都绑定一个回调机制。
selectors模块,可以根据不同的平台自动选择不同的实现
import select
import socket
server = socket.socket()
server.bind(("127.0.0.1", 8080))
server.setblocking(False)
server.listen(5)
read_list = [server]
while True:
# 如果server有新的连接,conn有新的消息,都会返回到第一个
# 写数据的时候,如果对方收的比较慢,则缓存区会满,此时也会阻塞。
read,write,e = select.select(read_list, [], []) # 监听server
for i in read:
if i is server:
conn, (ip, addr) = i.accept()
read_list.append(conn)
else:
data = i.recv(1024)
if len(data) == 0:
i.close()
read_list.remove(i)
continue
i.send(data.upper())
异步IO
异步IO
模块: asyncio模块
框架: sanic tronado twisted