(一)同步阻塞IO模型
1、IO就是输入和输出(即是读和写) 2、接收数据即为input,发送数据即为output的套接字 3、读文件即为input,写文件即为output 4、默认的套接字即为同步阻塞的套接字
(二)同步非阻塞IO模型
1、概念:用户发起read请求,如果内核数据没有到达,立刻返回。然后不断循环的去发起read请求,直到有数据就进行读取操作。 2、缺点:用户线程每次请求IO都可以立即返回,但是为了拿到有内容的数据,需要不断轮询,这无非就要消耗大量的cpu内存。(在实际的生活很少使用这种模型,而是在其他IO模型中使用这种模型的特性)
(三)非阻塞套接字
1、设置非阻塞:setblocking(False) 注意:当参数为True时,则为阻塞形式 2、accept、recv方法:这是两个阻塞方法,如果不阻塞,没有连接,没有数据会引发BlockingIoError,所以要用try.....except来捕获异常。
(四)同步非阻塞套接字实现并发服务器
思路:外循环不断用accept来接受连接,用一个列表把所有连接进来的对象存储进来,并把服务器端的socket对象设置为非阻塞。内循环用来对列表里的连接对象进行操作。
代码实例:import socket
server=socket.socket()
server.setblocking(False) #设置非阻塞
server.bind((' ',端口号))
server.listen(5)
client_list=[ ] #用来存储连接进来的客户端
while True:
try:
conn,adrr=server.accept()
conn.setblocking(False)
client_list.append((conn,addr))
print('连接:{}'.format(addr))
except Exception:
pass
for client,adrr in client_list:
try:
recv_data=client.recv(1024)
if recv_data:
print(recv_data.decode())
else:
client_list.remove((client,adrr))
client.close()
except Exception:
pass
(五)IO多路复用
1、epoll只在linux系统下存在;windows中没有,但是有select。 2、epoll本质是事件驱动Io。 3、使用步骤:(1)创建epoll (2)创建回调函数 (3)注册socket对象 (4)循环监听
(六)代码实例
通过epoll、Io多路复用来实现并发服务器
import socket
import selectors
server=socket.socket()
sever.bind((' ',端口号))
server.listen(10000)
def recv(soc):
data=soc.recv(1024)
if data:
soc.send(data)
else:
epoll_selector.unregister(soc)
soc.close()
def accept(soc):
conn,adrr=soc.accept()
epoll_selector.register(
conn,
selectors.EVENT_READ,
recv)
if __name=='__main__':
epoll_selector.DefaultSelector()
epoll_selector.register(
server,
selectors.EVENT_READ,
accept )
while True:
events=epoll_selector.select()
for key,mark in events:
sock=key.filedobj
callback=key.data
callback(sock)
网友评论