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
相关产品推荐
相关产品推荐

