标签:sock pytho set 磁盘 read locking 传输 blocking 二进制
IO input output
在内存中存在数据交换的操作都可以认为是IO操作
和终端交互 : input print
和磁盘交互 : read write
和网络交互 : recv send
IO密集型程序:在程序执行过程中存在大量IO操作,而cpu运算操作较少,消耗cpu较少,运行效率较低
计算密集型程序(CUP密集型程序):在程序执行中CPU运算较多,IO操作相对较少,消耗CPU大,运行速度快
# 设置非阻塞
from socket import *
from time import sleep,ctime
s = socket()
s.bind(('127.0.0.1',9999))
s.listen(3)
#将套接字设置为非阻塞
s.setblocking(False)
while True:
print("Waiting for connect...")
try:
c,addr = s.accept()
except BlockingIOError:
sleep(2)
print(ctime())
continue
else:
print("Connected from",addr)
while True:
data = c.recv(1024).decode()
if not data:
break
print(data)
c.send(ctime().encode())
c.close()
s.close()
将原本阻塞的函数设置一个最长阻塞时间,如果时间内条件达成则正常运行,如果仍然阻塞则视为超时,继续向下运行或产生异常
s.settimeout(sec)
设置套接字的超时时间
# 设置超时时间
from socket import *
from time import sleep,ctime
s = socket()
s.bind(('127.0.0.1',8888))
s.listen(3)
#将套接字设置超时时间
s.settimeout(5)
while True:
print("Waiting for connect...")
try:
c,addr = s.accept()
except timeout:
print(ctime())
continue
else:
print("Connect from",addr)
while True:
data = c.recv(1024).decode()
if not data:
break
print(data)
c.send(ctime().encode())
c.close()
s.close()
IO准备就绪:是一种IO必然要发生的临界状态
具体方案:
select --> linux unix windows
poll --> linux unix
epoll --> linux unix
import select
rs,ws,xs = select(rlist, wlist, xlist[, timeout])
from select import select
from socket import *
#创建套接字作为我们关注的IO
s = socket()
s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
s.bind(('0.0.0.0',9999))
s.listen(5)
rlist = [s]
wlist = []
xlist = [s]
while True:
#提交监测我们关注的IO等待IO发生
rs,ws,xs = select(rlist,wlist,xlist)
for r in rs:
if r is s:
c,addr = r.accept()
print("Connect from",addr)
rlist.append(c) #添加到关注列表
else:
data = r.recv(1024)
if not data:
rlist.remove(r)
r.close()
else:
print(data.decode())
# r.send(b'Receive your message')
#将客户端套接字放入wlist列表
wlist.append(r)
for w in ws:
w.send(b'Receive your message')
wlist.remove(w)
for x in xs:
if x is s:
s.close()
>>:右移
11 1011
14 1110
14 & 11 : 1010 一0则0
14 | 11 : 1111 一1则1
14 ^ 11 : 0101 相同为0不同为1
11 << 2 : 101100 右侧补零
14 >> 2 : 11
添加注册事件
p.register(s, POLLIN | POLLERR)
POLLIN POLLOUT POLLERR POLLHUP POLLNVAL
rlist wlist xlist 断开 无效数据
p.unregister(s) 从关注事件中移除
返回值:events 是一个列表,列表中给每一个元素都是一个元组,代表一个发生的IO事件
[(fileno, event),(),()....]
就绪IO的文件描述符, 具体就绪事件
需要通过文件描述符(fileno)找到对应的IO对象
{s.fileno() : s}
处理具体的IO
from socket import *
from select import *
#创建套接字作为我们关注的IO
s = socket()
s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
s.bind(('0.0.0.0',9999))
s.listen(5)
#创建poll对象
p = poll()
#fileno ---> IO对象的字典
fdmap = {s.fileno():s}
#注册关注的IO
p.register(s,POLLIN | POLLERR)
while True:
#进行IO监控
events = p.poll()
for fd,event in events:
if fd == s.fileno():
c,addr = fdmap[fd].accept()
print("Connect from",addr)
#添加新的关注事件
p.register(c,POLLIN | POLLHUP)
fdmap[c.fileno()] = c
elif event & POLLIN: # 若是真,POLLIN就绪
data = fdmap[fd].recv(1024)
if not data:
#客户端退出,从关注事件移除
p.unregister(fd)
fdmap[fd].close()
del fdmap[fd]
else:
print(data.decode())
fdmap[fd].send(b'Receive')
from socket import *
from select import *
#创建套接字作为我们关注的IO
s = socket()
s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
s.bind(('0.0.0.0',9999))
s.listen(5)
#创建epoll对象
p = epoll()
#fileno ---> IO对象的字典
fdmap = {s.fileno():s}
#注册关注的IO
p.register(s,EPOLLIN | EPOLLERR)
while True:
#进行IO监控
events = p.poll()
for fd,event in events:
if fd == s.fileno():
c,addr = fdmap[fd].accept()
print("Connect from",addr)
#添加新的关注事件
p.register(c,EPOLLIN | EPOLLHUP)
fdmap[c.fileno()] = c
elif event & EPOLLIN:
data = fdmap[fd].recv(1024)
if not data:
#客户端退出,从关注事件移除
p.unregister(fd)
fdmap[fd].close()
del fdmap[fd]
else:
print(data.decode())
fdmap[fd].send(b'Receive')
标签:sock pytho set 磁盘 read locking 传输 blocking 二进制
原文地址:https://www.cnblogs.com/haoenwei/p/10654537.html