1. 程式人生 > >python之select與epoll

python之select與epoll

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要看作業系統的支援)