<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                [toc] 下面將以socket網絡通信為例,分別通過非阻塞IO和多路復用IO來進行代碼實現 ## 非阻塞IO ### server端代碼 主要就是將setblocking設置為False后,通過捕獲拋出的異常,以判斷是否有新連接,是否有接受到數據,然后不停的while循環來實現 ~~~ import socket server=socket.socket() server.bind(('127.0.0.1',8800)) server.listen() server.setblocking(False) con_list=[] rm_list=[] while True: try: conn,addr=server.accept() con_list.append(conn) except BlockingIOError: for conn in con_list: try: msg=conn.recv(1024) conn.send(b'my server') except BlockingIOError:pass except ConnectionResetError: rm_list.append(conn) conn.close() for conn in rm_list: con_list.remove(conn) else: rm_list.clear() #刪除關閉的client server.close() ~~~ ### client端代碼 ~~~ import socket,os,time client=socket.socket() client.connect(('127.0.0.1',8800)) while True: msg='my client:%s'%os.getpid() print(msg) client.send(msg.encode()) time.sleep(1) print(client.recv(1024)) ~~~ ## 多路復用IO 多路復用,是使用了一個代理`select`來做監聽的動作,避免了前一種方式`while循環`的資源消耗 ### server端代碼 ~~~py import socket,select server = socket.socket() server.bind(('127.0.0.1', 8800)) server.listen(5) server.setblocking(False) #設置為非阻塞 print('server is start ......') rlist = [server, ] # 讀列表,初始只有server wlist = [] # 寫列表 xlist = [] # 異常列表 while True: rl, wl, xl = select.select(rlist, wlist, xlist) # print('rlist:', rlist) for sk in rl: if sk == server: # 如果是server則建立連接并添加conn到列表 conn, addr = sk.accept() rlist.append(conn) # else: # 如果是conn,則收發數據 try: conn = sk msg = conn.recv(1024).decode() if not msg:#客戶端關閉則刪除conn(linux) conn.close() rlist.remove(sock) continue print('接收消息:', msg) conn.send(msg.upper().encode()) except ConnectionResetError: #客戶端關閉則刪除conn(windows) conn.close() rlist.remove(conn) ~~~ ### client端代碼 ~~~py import socket client=socket.socket() client.connect(('127.0.0.1',8800)) while True: msg=input('>>:') if not msg:continue client.send(msg.encode()) data=client.recv(1024) print(data.decode( )) ~~~ ## 基于selectors的IO多路復用 **selectors模塊** * 此模塊允許基于選擇模塊原語構建高級別和高效的I / O多路復用。 * 鼓勵用戶使用此模塊,除非他們想要精確控制使用的os級別的原語。 注:selectors也是包裝了select高級的包裝內置函數,它包裝了select與epoll,優先使用epoll,windos內只支持select。 ### server端代碼 ~~~py import selectors import socket sock = socket.socket() sock.bind(('127.0.0.1', 8800)) sock.listen(5) sock.setblocking(False) sel = selectors.DefaultSelector() # 生成select實例對象 def read(conn, mask): try: data = conn.recv(1024) if not data: print('closing', conn) sel.unregister(conn) conn.close() return conn.send(data.upper() + b'_SB') except Exception: print('closing', conn) sel.unregister(conn) # 取消注冊 conn.close() # 關閉連接 def accept(sock, mask): conn, addr = sock.accept() print('-------', conn) # 注冊conn,回調 read函數 sel.register(conn, selectors.EVENT_READ, read) # 注冊server事件: # 參數1:sock 進行監聽 # 參數2:selectors.EVENT_READ 執行動作 # 參數3:accept,只要來一個鏈接就回調這個函數 sel.register(sock, selectors.EVENT_READ, accept) while True: print('wating....') events = sel.select() # 調用select:優先使用epoll # 默認阻塞,有活動鏈接就返回活動的鏈接列表 for key, mask in events: # callback相當于調accept函數 callback = key.data # 獲取函數內存地址,加入參數 # key.fileobj = 文件句柄 callback(key.fileobj, mask) ~~~ ### client端代碼 ~~~py import socket client=socket.socket() client.connect(('127.0.0.1',8800)) while True: msg=input('>>:') if not msg:continue client.send(msg.encode()) data=client.recv(1024) print(data.decode( )) ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看