基於select的網絡IO模型

#select  和    poll    和epoll的區別
    '''
      select和poll有一個共同的機制,都是採用輪訓的方式去詢問內核,有沒有數據準備好了
      select有一個最大監聽事件的限制,32位機限制1024,,6位機限制2048
      poll沒有,理論上poll能夠開啓無限大,1G內存大概夠你開10W個事件去監聽
      epoll是最好的,採用的是回調機制,解決了select和poll共同存在的問題
      並且epoll理論上也能夠開啓無限多個監聽事件
    '''

# IO多路複用
    '''
        阻塞IO
        非阻塞IO
        多路複用IO
        異步IO python實現不了,可是有tornado框架,天生自帶異步
    '''

#服務器端
import socket
import select

sk=socket.socket()
sk.bind(('127.0.0.1',8080))
sk.listen()

Conn_Del = []        #定義刪除列表
rlist = [sk]         #是用來讓select幫忙監聽的全部接口
# select:windows/linux是監聽事件有沒有數據到來
# poll:  linux   也能夠作select的工做
# epoll: linux   也能夠作相似的工做

while 1:
    r,w,x = select.select(rlist,[],[])  #將rlist傳給select,當rlist中哪一個接口有反應,就返回給r這個列表
    if r:
        for i in r:                     #循環遍歷,看看有反應的接口是sk仍是conn,由於若是是sk,後面會把conn也加到這個列表中
            if i == sk:
                #若是是sk,代表有客戶端的鏈接請求
                conn,addr = i.accept()
                rlist.append(conn)      #把新的客戶端的鏈接,添加到rlist,繼續讓select幫忙監聽
            else:
                #若是是conn,表明客戶端請求發送數據了(此時客戶端已經鏈接上了)
                #下面的異常處理模型和非阻塞IO模型解決阻塞IO模型相似
                try:
                    msg = i.recv(1024).decode('utf-8')
                    if not msg:
                        #客戶端正常關閉返回給服務器端一個空,即客戶端執行了close()
                        Conn_Del.append(i)
                        i.close()
                    else:
                        #服務器端的邏輯層(以字符串大寫的形式返回給客戶端)
                        print("接收到來自{}客戶端的消息{}".format(i,msg))
                        i.send(msg.upper().encode('utf-8'))
                except ConnectionResetError:
                    #客戶端強制關閉
                    pass

        if Conn_Del:
            for conn in Conn_Del:
                rlist.remove(conn)
            Conn_Del.clear()


sk.close()




#客戶端
import socket
sk = socket.socket()
sk.connect(('127.0.0.1',8080))

while 1:
    msg_s = input('>>>')
    if not msg_s:continue
    if msg_s == 'q':break
    sk.send(msg_s.encode('utf-8'))
    print(sk.recv(1024).decode('utf-8'))
sk.close()
相關文章
相關標籤/搜索