Python使用異步線程池如何實現(xiàn)異步TCP服務(wù)器交互
更新時間:2023年11月10日 08:50:23 作者:Rnan-prince
這篇文章主要介紹了Python使用異步線程池如何實現(xiàn)異步TCP服務(wù)器交互問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
背景
實現(xiàn)客戶端與服務(wù)端交互,由于效率原因,要發(fā)送與接收異步,提高效率。
需要多線程,本文用線程池管理。
common代碼
import pickle import struct import time def send_msg(conn, data): time.sleep(1) msg = pickle.dumps(data) msg = struct.pack('>I', len(msg)) + msg conn.sendall(msg) return data, len(msg) def recv_from(conn, n): data = b'' handle_len = 0 while handle_len < n: packet = conn.recv(n - handle_len) if not packet: return None handle_len += len(packet) data += packet return data def recv_msg(conn): struct_msg_len = recv_from(conn, 4) if not struct_msg_len: return None, 0 msg_len = struct.unpack('>I', struct_msg_len)[0] msg = recv_from(conn, msg_len) msg = pickle.loads(msg) return msg, msg_len
客戶端
#!/usr/bin/python # -*- coding: utf-8 -*- import time import select import socket import threading from threading import Thread from concurrent.futures import as_completed from concurrent.futures import ThreadPoolExecutor from common import send_msg, recv_msg sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 生成socket sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 不經(jīng)過WAIT_TIME,直接關(guān)閉 sock.setblocking(False) # 設(shè)置非阻塞編程 inputs = [sock, ] executor = ThreadPoolExecutor(max_workers=3) # 設(shè)置線程池最大數(shù)量 print('client start!!!') try: sock.connect(("127.0.0.1", 789)) except Exception as e: print(e) def handle_received_data(data): print("接收服務(wù)端信息:", data) time.sleep(1) return def receive_service_data(): """接收服務(wù)端返回的數(shù)據(jù)并處理""" while True: try: r_list, w_list, e_list = select.select(inputs, [], [], 1) for event in r_list: data, data_len = recv_msg(event) if data: try: executor.submit(handle_received_data, data) except Exception as e: print(threading.current_thread(), threading.active_count()) print(e) else: print("遠(yuǎn)程斷開連接") inputs.remove(event) exit() except OSError as e: import traceback print(traceback.format_exc()) print(e) exit() def send_client_data(size=100): """發(fā)送客戶端數(shù)據(jù)""" executors = [] for i in range(size): exe = executor.submit(send_msg, sock, {'data': i}) executors.append(exe) for feature in as_completed(executors): try: data, data_len = feature.result() except Exception as e: print(e) else: print(f"客戶端發(fā)送數(shù)據(jù):{data}, len:{data_len}") if __name__ == '__main__': T1 = time.time() # 啟動接受服務(wù)端數(shù)據(jù)的線程 Thread(target=receive_service_data).start() # 發(fā)送客戶端數(shù)據(jù) send_client_data(size=10) print('all_time:', time.time() - T1)
服務(wù)端
#!/usr/bin/python # -*- coding: utf-8 -*- import time import socket import select import threading from concurrent.futures import ThreadPoolExecutor from common import send_msg, recv_msg sock = socket.socket() sock.bind(('127.0.0.1', 789)) sock.setblocking(False) sock.listen() inputs = [sock, ] lock = threading.Lock() executor = ThreadPoolExecutor(max_workers=3) # 設(shè)置線程池最大數(shù)量 print('service start!!!') def handle_received_data(event, data): time.sleep(1) send_msg(event, data) print(f"服務(wù)端發(fā)送數(shù)據(jù):{data}") while True: r_list, w_list, e_list = select.select(inputs, [], [], 1) for event in r_list: if event == sock: print("新的客戶端連接") new_sock, addresses = event.accept() inputs.append(new_sock) else: data, msg_len = recv_msg(event) if data: print("接收到客戶端信息", data) executor.submit(handle_received_data, event, data) else: print("客戶端斷開連接") inputs.remove(event)
運行結(jié)果
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python mlxtend庫數(shù)據(jù)科學(xué)和機器學(xué)習(xí)補充工具功能探索
這篇文章主要介紹了Python mlxtend庫數(shù)據(jù)科學(xué)和機器學(xué)習(xí)補充工具功能探索,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01python利用requests庫進(jìn)行接口測試的方法詳解
在python的標(biāo)準(zhǔn)庫中,雖然提供了urllib,utllib2,httplib,但是做接口測試,requests真心好,正如官方說的,“讓HTTP服務(wù)人類”,一言以蔽之,說明一切,這篇文章主要給大家介紹了關(guān)于python利用requests庫進(jìn)行接口測試的相關(guān)資料,需要的朋友可以參考下2018-07-07python基于Node2Vec實現(xiàn)節(jié)點分類及其可視化示例詳解
這篇文章主要為大家介紹了python基于Node2Vec實現(xiàn)節(jié)點分類及其可視化示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04Python常見數(shù)據(jù)類型轉(zhuǎn)換操作示例
這篇文章主要介紹了Python常見數(shù)據(jù)類型轉(zhuǎn)換操作,結(jié)合實例形式分析了Python針對列表、集合、元組、字典等數(shù)據(jù)類型轉(zhuǎn)換的相關(guān)操作技巧,需要的朋友可以參考下2019-05-05matlab調(diào)用python的各種方法舉例子詳解
為了發(fā)揮matlab的繪圖優(yōu)勢+原先python寫好的功能組合方式,下面這篇文章主要給大家介紹了關(guān)于matlab調(diào)用python的各種方法,需要的朋友可以參考下2023-09-09python數(shù)據(jù)寫入Excel文件中的實現(xiàn)步驟
Python作為時下流行的語言,數(shù)據(jù)寫入Excel是必要的操作,下面這篇文章主要給大家介紹了關(guān)于python數(shù)據(jù)寫入Excel文件中的簡單實現(xiàn)方法,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-04-04