Python使用異步線程池如何實(shí)現(xiàn)異步TCP服務(wù)器交互
背景
實(shí)現(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)運(yùn)行結(jié)果

總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python mlxtend庫數(shù)據(jù)科學(xué)和機(jī)器學(xué)習(xí)補(bǔ)充工具功能探索
這篇文章主要介紹了Python mlxtend庫數(shù)據(jù)科學(xué)和機(jī)器學(xué)習(xí)補(bǔ)充工具功能探索,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01
python利用requests庫進(jìn)行接口測試的方法詳解
在python的標(biāo)準(zhǔn)庫中,雖然提供了urllib,utllib2,httplib,但是做接口測試,requests真心好,正如官方說的,“讓HTTP服務(wù)人類”,一言以蔽之,說明一切,這篇文章主要給大家介紹了關(guān)于python利用requests庫進(jìn)行接口測試的相關(guān)資料,需要的朋友可以參考下2018-07-07
python基于Node2Vec實(shí)現(xiàn)節(jié)點(diǎn)分類及其可視化示例詳解
這篇文章主要為大家介紹了python基于Node2Vec實(shí)現(xiàn)節(jié)點(diǎn)分類及其可視化示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04
Python常見數(shù)據(jù)類型轉(zhuǎn)換操作示例
這篇文章主要介紹了Python常見數(shù)據(jù)類型轉(zhuǎn)換操作,結(jié)合實(shí)例形式分析了Python針對列表、集合、元組、字典等數(shù)據(jù)類型轉(zhuǎn)換的相關(guān)操作技巧,需要的朋友可以參考下2019-05-05
matlab調(diào)用python的各種方法舉例子詳解
為了發(fā)揮matlab的繪圖優(yōu)勢+原先python寫好的功能組合方式,下面這篇文章主要給大家介紹了關(guān)于matlab調(diào)用python的各種方法,需要的朋友可以參考下2023-09-09
python數(shù)據(jù)寫入Excel文件中的實(shí)現(xiàn)步驟
Python作為時下流行的語言,數(shù)據(jù)寫入Excel是必要的操作,下面這篇文章主要給大家介紹了關(guān)于python數(shù)據(jù)寫入Excel文件中的簡單實(shí)現(xiàn)方法,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-04-04

