- 阻塞IO
blocking IO的特点就是在IO执行的两个阶段(等待数据和拷贝数据两个阶段)都被block了
# 服务端
from socket import *
from threading import Thread
def communicate(conn):
while True:
try:
data = conn.recv(1024)
if not data: break
conn.send(data.upper())
except ConnectionResetError:
break
conn.close()
server = socket(AF_INET, SOCK_STREAM)
server.bind(('127.0.0.1', 8080))
server.listen(5)
while True:
print('start...')
conn, addr = server.accept()
print(addr)
t = Thread(target=communicate, args=(conn,))
t.start()
server.close()
# 客户端
from socket import *
client = socket(AF_INET, SOCK_STREAM)
client.connect(('127.0.0.1', 8080))
while True:
msg = input('>>: ').strip()
if not msg: continue
client.send(msg.encode('utf-8'))
data = client.recv(1024)
print(data.decode('utf-8'))
client.close()
- 非阻塞IO
在非阻塞式IO中,用户进程其实是需要不断的主动询问kernel数据准备好了没有。
# 服务端
from socket import *
server = socket(AF_INET, SOCK_STREAM)
server.bind(('127.0.0.1', 8080))
server.listen(5)
server.setblocking(False)
print('start......')
rlist = []
wlist = []
while True:
try:
conn, addr = server.accept()
rlist.append(conn)
print(rlist)
except BlockingIOError:
# print('干其他的活')
# 收消息
del_rlist = []
for conn in rlist:
try:
data = conn.recv(1024)
if not data:
del_rlist.append(conn)
continue
wlist.append((conn, data.upper()))
except BlockingIOError:
continue
except Exception:
conn.close()
del_rlist.append(conn)
# 发消息
del_wlist = []
for item in wlist:
try:
conn = item[0]
data = item[1]
conn.send(data)
del_wlist.append(item)
except BlockingIOError:
pass
for item in del_wlist:
wlist.remove(item)
for conn in del_rlist:
rlist.remove(conn)
server.close()
- 多路复用IO
select的优势在于可以处理多个连接,不适用于单个连接
# 服务端
import select
from socket import *
server = socket(AF_INET, SOCK_STREAM)
server.bind(('127.0.0.1', 8080))
server.listen(5)
server.setblocking(False)
print('start......')
rlist = [server, ]
wlist = []
wdata = {}
while True:
r1, w1, x1 = select.select(rlist, wlist, [], 0.5)
print('r1', r1)
print('w1', w1)
for sock in r1:
if sock == server:
conn, addr = sock.accept()
rlist.append(conn)
else:
try:
data = sock.recv(1024)
if not data:
sock.close()
rlist.remove(sock)
continue
wlist.append(sock)
wdata[sock] = data.upper()
except Exception:
sock.close()
rlist.remove(sock)
for sock in w1:
data = wdata[sock]
sock.send(data)
wlist.remove(sock)
wdata.pop(sock)
server.close()