最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python 基于隊(duì)列實(shí)現(xiàn) tcp socket 連接池的方法

 更新時(shí)間:2025年05月05日 11:43:45   作者:授客  
這篇文章主要介紹了Python 基于隊(duì)列實(shí)現(xiàn) tcp socket 連接池的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧

連接池實(shí)現(xiàn)

socket_pool.py

# -*- coding:utf-8 -*-
import socket
import time
import threading
import os
import logging
import traceback
from queue import Queue, Empty
_logger = logging.getLogger('mylogger')
class SocketPool:
    def __init__(self, host, port, min_connections=10, max_connections=10):
        '''
        初始化Socket連接池
        :param host: 目標(biāo)主機(jī)地址
        :param port: 目標(biāo)端口號(hào)
        :param min_connections: 最小連接數(shù)
        :param max_connections: 最大連接數(shù)
        '''
        self.host = host
        self.port = port
        self.min_connections = min_connections
        self.max_connections = max_connections
        self.busy_sockets_dict = {} # 存放從連接池取出的socket的id
        self._sock_lock = threading.Lock()  # 線程鎖保證計(jì)數(shù)正確
        self._pool = Queue(max_connections)  # 基于線程安全的隊(duì)列存儲(chǔ)連接
        self._lock = threading.Lock()        # 線程鎖保證資源安全:
        self._init_pool()                    # 預(yù)創(chuàng)建連接
        self._start_health_check()           # 啟動(dòng)連接健康檢查線程
    def _init_pool(self):
        '''預(yù)創(chuàng)建連接并填充到池中'''
        for _ in range(self.min_connections):
            sock = self._create_socket()
            self._pool.put(sock)
    def _create_socket(self):
        '''創(chuàng)建新的Socket連接'''
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            sock.connect((self.host, self.port))
            return sock
        except socket.error as e:
            raise ConnectionError(f'Failed to connect: {e}')  # 連接失敗拋出異常
    def _start_health_check(self):
        '''啟動(dòng)后臺(tái)線程定期檢查連接有效性'''
        def check():
            while True:
                with self._lock:
                    for _ in range(self._pool.qsize()):
                        sock = self._pool.get()
                        self.busy_sockets_dict[sock] = 1
                        try:
                            sock.send(b'PING<END>')  # 發(fā)送心跳包驗(yàn)證連接狀態(tài)
                            # 以下 11 為服務(wù)端返回?cái)?shù)據(jù)字節(jié)長度,不能亂寫,否則會(huì)導(dǎo)致獲取非健康檢查響應(yīng)報(bào)文數(shù)據(jù)存在多余內(nèi)容,不符合格式,從而導(dǎo)致數(shù)據(jù)解析問題
                            sock.recv(11)
                            self._pool.put(sock)
                            self.busy_sockets_dict.pop(sock)
                        except (socket.error, ConnectionResetError):
                            _logger.error('socket連接健康檢查出錯(cuò):%s, 關(guān)閉失效連接并創(chuàng)建新連接替換' % traceback.format_exc())
                            sock.close()  # 關(guān)閉失效連接并創(chuàng)建新連接替換
                            self.busy_sockets_dict.pop(sock)
                            new_sock = self._create_socket()
                            self._pool.put(new_sock)
                    # 如果sock數(shù)量小于最小數(shù)量,則補(bǔ)充
                    for _ in range(0, self.min_connections - self._pool.qsize()):
                        new_sock = self._create_socket()
                        self._pool.put(new_sock)
                time.sleep(60)  # 每60秒檢查一次
        threading.Thread(target=check, daemon=True).start()
    def get_connection(self):
        '''
        從池中獲取一個(gè)可用連接
        :return: socket對(duì)象
        '''
        with self._sock_lock:
            if self._pool.empty():
                if len(self.busy_sockets_dict.keys()) < self.max_connections:
                    new_sock = self._create_socket()
                    self.busy_sockets_dict[new_sock] = 1
                    return new_sock
                else:
                    raise Empty('No available connections in pool')
            else:
                try:
                    sock = self._pool.get(block=False)
                    self.busy_sockets_dict[sock] = 1
                    return sock
                except Exception:
                    _logger.error('獲取socket連接出錯(cuò):%s' % traceback.format_exc())
                    raise
    def release_connection(self, sock):
        '''
        將連接歸還到池中
        :param sock: 待歸還的socket對(duì)象
        '''
        if not sock._closed:
            self._pool.put(sock)
        if sock in self.busy_sockets_dict:
            self.busy_sockets_dict.pop(sock)
    def close_all(self):
        '''關(guān)閉池中所有連接'''
        while not self._pool.empty():
            sock = self._pool.get()
            sock.close()
            self.busy_sockets_dict.pop(sock.id)
        self.busy_sockets_dict = {} # 兜底
host = os.environ.get('MODBUS_TCP_SERVER_HOST', '127.0.0.1')
port = int(os.environ.get('MODBUS_TCP_SERVER_PORT', '9000'))
min_connections = int(os.environ.get('DJANGO_SOCKET_POOL_MAX_CONNECTIONS', '10'))
max_connections = int(os.environ.get('DJANGO_SOCKET_POOL_MAX_CONNECTIONS', '100'))
socketPool = SocketPool(host, port, min_connections, max_connections)

使用連接池

from socket_pool import socketPool
def send_socket_msg(data):
    global socketPool
    try:
        sock = None
        # 獲取連接(支持超時(shí)控制)
        sock = socketPool.get_connection()
        # 發(fā)送數(shù)據(jù)
        sock.sendall(data.encode('utf-8'))
    except Exception:
        error_msg = '發(fā)送消息出錯(cuò):%s' % traceback.format_exc()
        _logger.error(error_msg)
        if sock is not None:
            sock.close()
            socketPool.release_connection(sock)
        return send_socket_msg(data)
    response = ''
    try:
        while True:
            chunk = sock.recv(4096)
            chunk = chunk.decode('utf-8')
            response += chunk
            if response.endswith('<END>'):
                response = response.rstrip('<END>')
                return {'success':True, 'message':response}
    except Exception:
        error_msg = '獲取消息出錯(cuò):%s' % traceback.format_exc()
        _logger.error(error_msg)
        return {'success':False, 'message': error_msg}
    finally:
        # 必須歸還連接!
        socketPool.release_connection(sock)

到此這篇關(guān)于Python 基于隊(duì)列實(shí)現(xiàn) tcp socket 連接池的文章就介紹到這了,更多相關(guān)Python tcp socket 連接池內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 使用PyCharm批量爬取小說的完整代碼

    使用PyCharm批量爬取小說的完整代碼

    這篇文章主要介紹了使用PyCharm批量爬取小說,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • 使用Python+Appuim 清理微信的方法

    使用Python+Appuim 清理微信的方法

    這篇文章主要介紹了使用Python+Appuim 清理微信,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • 詳解Pytorch如何利用yaml定義卷積網(wǎng)絡(luò)

    詳解Pytorch如何利用yaml定義卷積網(wǎng)絡(luò)

    大多數(shù)卷積神經(jīng)網(wǎng)絡(luò)都是直接通過寫一個(gè)Model類來定義的,這樣寫的代碼其實(shí)是比較好懂,也很方便。但是本文將介紹另一個(gè)方法:利用yaml定義卷積網(wǎng)絡(luò),感興趣的可以了解一下
    2022-10-10
  • Pytorch?和?Tensorflow?v1?兼容的環(huán)境搭建方法

    Pytorch?和?Tensorflow?v1?兼容的環(huán)境搭建方法

    這篇文章主要介紹了搭建Pytorch?和?Tensorflow?v1?兼容的環(huán)境,本文是小編經(jīng)過多次實(shí)踐得到的環(huán)境配置教程,給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-11-11
  • 使用Python對(duì)Syslog信息進(jìn)行分析并繪圖的實(shí)現(xiàn)

    使用Python對(duì)Syslog信息進(jìn)行分析并繪圖的實(shí)現(xiàn)

    這篇文章主要介紹了使用Python對(duì)Syslog信息進(jìn)行分析并繪圖的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • Python 啟動(dòng)時(shí)選擇32位 或64位版的操作

    Python 啟動(dòng)時(shí)選擇32位 或64位版的操作

    這篇文章主要介紹了Python 啟動(dòng)時(shí)選擇32位 或64位版的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03
  • 對(duì)python調(diào)用RPC接口的實(shí)例詳解

    對(duì)python調(diào)用RPC接口的實(shí)例詳解

    今天小編就為大家分享一篇對(duì)python調(diào)用RPC接口的實(shí)例詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01
  • Python?Melt函數(shù)將寬格式的數(shù)據(jù)表轉(zhuǎn)換為長格式

    Python?Melt函數(shù)將寬格式的數(shù)據(jù)表轉(zhuǎn)換為長格式

    在數(shù)據(jù)處理和清洗中,melt函數(shù)是Pandas庫中一個(gè)強(qiáng)大而靈活的工具,它的主要功能是將寬格式的數(shù)據(jù)表轉(zhuǎn)換為長格式,從而更方便進(jìn)行分析和可視化,本文將深入探討melt函數(shù)的用法、參數(shù)解析以及實(shí)際應(yīng)用場(chǎng)景
    2023-12-12
  • 使用 Python 遍歷目錄樹的方法

    使用 Python 遍歷目錄樹的方法

    這篇文章主要介紹了使用 Python 遍歷目錄樹的方法,文中給大家提到了Python os.walk() 函數(shù)的相關(guān)知識(shí),通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2020-02-02
  • python之yield表達(dá)式學(xué)習(xí)

    python之yield表達(dá)式學(xué)習(xí)

    這篇文章主要介紹了python之yield表達(dá)式學(xué)習(xí),python中有一個(gè)略微奇怪的表達(dá)式叫yield expression,本文就來探究一下這是個(gè)什么東西,需要的朋友可以參考下
    2014-09-09

最新評(píng)論

阳泉市| 喀喇沁旗| 广德县| 内乡县| 兴山县| 于田县| 天峨县| 大同县| 大安市| 额尔古纳市| 玉田县| 扶余县| 义马市| 满洲里市| 仁怀市| 河南省| 镶黄旗| 镇远县| 东台市| 孙吴县| 湘西| 德庆县| 湘西| 元朗区| 岑溪市| 耒阳市| 南丰县| 中牟县| 诸暨市| 六盘水市| 农安县| 西安市| 宕昌县| 东明县| 乌兰浩特市| 长垣县| 贺兰县| 彩票| 兴和县| 开鲁县| 祁连县|