python之select與epoll
阿新 • • 發佈:2018-11-10
select的用法寫網路socket的服務端
詳解在註釋裡
import select import socket import queue server = socket.socket() server.bind(('localhost',9000)) server.listen(1000) server.setblocking(False) #設定非阻塞模式 #accept不會堵塞了,沒連線會報錯 inputs = [server,] #監測的列表 outputs = [] #返回的連線列表 msg_dic = {} #訊息佇列字典 while True: readable, writeable, exceptional = select.select(inputs, outputs, inputs) for r in readable: if r is server: # 如果來的是新連線(server活躍) conn, addr = server.accept() print('來了個新連線:', addr) inputs.append(conn) msg_dic[conn] = queue.Queue() else: # 來的是連線 data = r.recv(1024) print('收到', data) msg_dic[r].put(data) outputs.append(r) for w in writeable: # 要返回給客戶端的連線列表 data_w = msg_dic[w].get() # 取得訊息佇列中的元素 print(data_w) w.send(data_w) # 返回資料 print('send done') outputs.remove(w) # 確保下次迴圈的時候writeable,不返回這個已經處理完的連線了 for e in exceptional: if e in outputs: outputs.remove(e) # 如果在返回列表裡,就刪掉outputs裡的e inputs.remove(e) # 刪除檢測列表裡的e del msg_dic[e] # 刪除訊息佇列
然後是客戶端:
import socket HOST = 'localhost' PORT = 9000 s = socket.socket() s.connect((HOST,PORT)) while True: msg = bytes(input('>>:'), encoding='utf8') s.sendall(msg) data = s.recv(1024) print('收到',data)
python中,Select已經封裝好,在python裡是selectors模組,裡面其實用的是epoll(具體到底是select還是epoll要看作業系統的支援)