You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyBluez蓝牙Socket连接数小时后莫名中断,寻求解决方案

蓝牙Socket长连接数小时后中断问题

环境与现象

  • 服务端:Ubuntu 22.04 迷你PC,基于PyBluez开发
  • 客户端:2台RPi 4,同样使用PyBluez实现
  • 异常表现:初始数据传输正常,运行数小时后传输中断;蓝牙系统连接状态显示正常,但程序停止收发日志;重启程序无法恢复,仅重启服务端PC能暂时解决;已排除缓冲区溢出、CPU/内存占用过高问题。

相关代码片段

服务端客户端处理线程

# thread for each client connection
def handle_client(connection):
    while True:
        try:
            data = connection.recv(1024).decode('utf-8')
            if not data:
                break
            reply = f'Received from {str(connection)}'
            connection.sendall(reply)
        except Exception as e:
            print(str(e))
            connection.close()

    connection.close()
...

客户端循环逻辑

...
while True:
    try:
        data = MacAddr #MacAddr obtained using subprocess
        conn.sendall(data + '\n')
        res = conn.recv(1024).decode('utf-8')
    except Exception as e:
        # attempt to reconnect to server
        ...
...

问题定位与解决方案

核心问题推测

  1. PyBluez底层资源泄漏:服务端异常处理仅关闭连接,未确保线程正常退出,导致系统蓝牙资源被耗尽,无法维持现有连接或处理新请求。
  2. 静默链路失效未检测:蓝牙连接状态显示正常,但实际链路已静默断开,recv()调用无限阻塞,导致线程挂起,停止处理数据。
  3. 半开连接未清理:客户端意外断开后,服务端recv()持续阻塞,占用线程资源,累积后导致服务端无响应。

具体修复方案

  1. 完善服务端线程与超时处理
    给recv()设置超时,避免无限阻塞,同时确保异常后线程正常退出:

    import socket
    
    def handle_client(connection):
        # 设置30秒接收超时,避免无限阻塞
        connection.settimeout(30)
        try:
            while True:
                try:
                    data = connection.recv(1024).decode('utf-8')
                    if not data:
                        break
                    reply = f'Received from {str(connection)}'
                    connection.sendall(reply)
                except socket.timeout:
                    # 超时发送心跳包检测链路
                    connection.sendall(b'HEARTBEAT')
                    continue
                except Exception as e:
                    print(f"Client error: {str(e)}")
                    break
        finally:
            connection.close()
            print(f"Closed connection: {str(connection)}")
    
  2. 添加双向心跳机制

    • 客户端:每固定周期发送心跳包,若连续3次未收到服务端响应,触发重连逻辑
    • 服务端:收到心跳包立即回复,若连续3个周期未收到客户端心跳,主动断开连接并清理资源
  3. 优化服务端连接管理

    • 维护活跃连接列表,定期遍历检查连接状态
    • 使用线程池(如concurrent.futures.ThreadPoolExecutor)管理客户端线程,避免无限制创建线程耗尽资源
  4. 调整系统蓝牙配置
    修改Ubuntu服务端/etc/bluetooth/main.conf,添加以下配置防止链路休眠:

    AutoEnable=true
    DiscoverableTimeout=0
    PairableTimeout=0
    

    重启蓝牙服务:sudo systemctl restart bluetooth

  5. 升级或替换PyBluez
    PyBluez对现代蓝牙协议的支持存在兼容性问题,可尝试升级到最新版本,或改用bleak(针对BLE场景)、原生蓝牙Socket结合bluetoothctl的实现方式。

内容的提问来源于stack exchange,提问作者baeksangyeol

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 08:54:17