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

BlueZ下QBluetoothSocket连接多台SPP设备无connected信号问题

QBluetoothSocket连接第二台经典蓝牙SPP设备时卡在ConnectingState问题

问题现象

使用QBluetoothSocket作为客户端,向两台经典蓝牙(BT Classic)SPP服务器发起连接,两台SPP服务分别运行在已与PC完成配对的独立ESP32设备上。
编写专用类处理与已知蓝牙地址设备的SPP连接,仅连接单台设备时功能运行完全正常;但调用QBluetoothSocket::connectToService()尝试连接第二台设备时,PC侧实际已与设备建立连接(ESP32端可正确上报连接状态),但对应QBluetoothSocket实例始终停留在ConnectingState状态,永远不会触发第二台设备对应的QBluetoothSocket::connected()信号。
运行环境为搭载BlueZ协议栈的Linux系统。

参考连接处理类实现

#include <QtCore/qmetaobject.h>

#include "bclassichandler.h"

BTClassicHandler::BTClassicHandler( QObject *parent ) : QObject{ parent } {}

BTClassicHandler::~BTClassicHandler() {}

void BTClassicHandler::connect( const QBluetoothAddress &btAddr )
{
    if ( m_socket ) return;

    m_socket = new QBluetoothSocket( QBluetoothServiceInfo::RfcommProtocol );
    qDebug() << "Created Socket for " << btAddr.toString();

    qDebug() << "Connecting to SPP on " << btAddr.toString();

    QObject::connect( m_socket, &QBluetoothSocket::readyRead, this,
                      &BTClassicHandler::onSocketRead );
    QObject::connect( m_socket, &QBluetoothSocket::connected, this,
                      &BTClassicHandler::onSocketConnected );
    QObject::connect( m_socket, &QBluetoothSocket::disconnected, this,
                      &BTClassicHandler::onSocketDisconnected );
    QObject::connect( m_socket, &QBluetoothSocket::errorOccurred, this,
                      &BTClassicHandler::onSocketError );
    QObject::connect( m_socket, &QBluetoothSocket::stateChanged, this,
                      &BTClassicHandler::onStateChanged );

    setAddress( btAddr );

    m_socket->connectToService( btAddr, QBluetoothUuid::ServiceClassUuid::SerialPort );
}

void BTClassicHandler::disconnect()
{
    delete m_socket;
    m_socket = nullptr;
}

void BTClassicHandler::write( QString data ) {}

void BTClassicHandler::setAddress( const QBluetoothAddress &btAddr )
{
    m_btAddr = btAddr;
}

void BTClassicHandler::setAddress( QString btAddr )
{
    m_btAddr = QBluetoothAddress( btAddr );
}

QBluetoothAddress BTClassicHandler::getAddress()
{
    return m_btAddr;
}

bool BTClassicHandler::isConnected()
{
    if ( !m_socket ) return false;
    return ( m_socket->state() == QBluetoothSocket::SocketState::ConnectedState );
}

/* Private Slots */

void BTClassicHandler::onSocketConnected() // <<<<< 第二台设备连接时该槽函数永远不会被触发 !!!!
{
    qDebug() << "Connected to " << m_btAddr.toString();
    emit sig_BTConnected( m_btAddr );
}

void BTClassicHandler::onSocketDisconnected()
{
    qDebug() << "Disconnected from " << m_btAddr.toString();
}

void BTClassicHandler::onSocketRead() {}

void BTClassicHandler::onSocketError( QBluetoothSocket::SocketError error )
{
    QMetaEnum metaEnum = QMetaEnum::fromType<QBluetoothSocket::SocketError>();
    QString errorString = metaEnum.valueToKey( static_cast<int>( error ) );

    qDebug() << "Socket Error " << m_btAddr.toString() << " :" << errorString;
}

void BTClassicHandler::onStateChanged( QBluetoothSocket::SocketState state )
{
    QMetaEnum metaEnum = QMetaEnum::fromType<QBluetoothSocket::SocketState>();
    QString stateString = metaEnum.valueToKey( static_cast<int>( state ) );

    qDebug() << "State Changed " << m_btAddr.toString() << " : " << stateString;
}

运行环境版本

  • Qt 6.2.4
  • BlueZ 5.5.3
  • Ubuntu 20.04

排查结果

经工具验证,BlueZ实际已成功建立连接:bluetoothctl、btmon工具均上报连接成功,BlueZ也通过DBus发送了连接成功消息,但Qt侧的connected信号始终未被触发。

临时解决方案

未找到Qt原生实现下的修复方案,临时绕过方案为基于Linux AF_BLUETOOTH原生套接字自行实现蓝牙套接字类。该实现逻辑也是Qt对5.46以下版本BlueZ的适配方案,可参考qtConnectivity模块中的QBluetoothSocketPrivateBluez类获取实现思路。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 12:06:19