【Python】多路复用型IO

from socket import *
import select


class Server(object):
def __init__(self, ip_bind=('127.0.0.1', 8080)):
self.head_buffer = 1024
self.coding = 'utf-8'
self.server = socket(AF_INET, SOCK_STREAM)
self.server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
self.server.bind(ip_bind)
self.server.listen(50)
self.server.setblocking(False) # 非阻塞模型IO

self.rlist = [self.server, ] # 用于存放准备连接socket的列表, 包括监听socket 和 链接socket
self.fd_rlist = [] # rlist 中的socket一旦受到数据就把socket放这里
self.recv_dict = [] # 用于存放待处理的接收数据列表

self.wlist = [] # 用于存放准备发数据的socket列表
self.fd_wlist = [] # wlist 中一旦有socket发了有准备发送的数据就把socket放这里
self.send_dict = [] # 用于存放待发送的数据列表

self.xlist = [] # 用于存放异常的列表
self.fd_xlist = []

def run(self):
while 1:
self.fd_rlist, self.fd_wlist, self.fd_xlist = select.select(self.rlist, self.wlist, self.xlist, 0.5)
# print('rl', self.fd_rlist)
# print('wl', self.fd_wlist)

for conn in self.fd_rlist:
if conn == self.server:
self.connect(conn)
else:
self.recv(conn)
self.work()

for conn in self.fd_wlist:
self.send(conn)

def connect(self, server):
conn, address_link = server.accept()
self.rlist.append(conn)

def recv(self, conn):
try:
msg = conn.recv(self.head_buffer)
if not msg:
self.rlist.remove(conn)
return
data = msg.decode(self.coding)
self.recv_dict.append((conn, data))
self.wlist.append(conn)
except Exception:
self.rlist.remove(conn)

def work(self):
del_list = []
for conn, data in self.recv_dict:
del_list.append((conn, data))
data = data.upper().encode(self.coding)
self.send_dict.append((conn, data))

for data in del_list:
self.recv_dict.remove(data)

def send(self, conn):
del_list = []
try:
for conn1, data in self.send_dict:
if conn == conn1:
conn.send(data)
del_list.append((conn1, data))
self.wlist.remove(conn)
except Exception:
self.rlist.remove(conn)
finally:
for data in del_list:
self.send_dict.remove(data)


if __name__ == '__main__':
s = Server()
s.run()
posted @ 2018-08-26 18:09  caya  阅读(145)  评论(0编辑  收藏  举报