繁体   English   中英

使用Qt通过蓝牙发送多个原始数据包

[英]Sending multiple raw packet over Bluetooth with Qt

我编写了此Python代码段(使用pybluez)以通过L2CAP发送原始的BNEP蓝牙数据包。 目的是进行一些类似模糊测试。

 BNEP_PSM = 0x000F
 btSock = bluetooth.BluetoothSocket(bluetooth.L2CAP)
 btSock.connect(('<some BDADDR>', BNEP_PSM))

 for i in range(10):
    btSock.send('<some payload>')

即使工作负载格式错误,这也可以正常工作,并且可以按预期创建多个BNEP数据包。

现在,我正在尝试使用Qt在C ++中编写相同的函数,但是它的工作方式不同。 该代码的摘录如下:

QBluetoothSocket btSock(QBluetoothServiceInfo::L2capProtocol);
btSock.connectToService(QBluetoothAddress("<some BDADDR>"), QBluetoothUuid::Bnep);

QObject::connect(&btSock, &QBluetoothSocket::connected, [&btSock](){
    int i = 10;
    while (i--)
        btSock.write("<some payload>");
});

i = 1运行它可以很好地发送具有指定有效负载的单个数据包。 i = 10运行它会导致单个包的有效载荷等于指定有效载荷的十倍

例如,在3的循环中设置有效载荷“ AAAA”将导致在第一种情况下使用Python

+------------+----+       +------------+----+       +------------+----+
|L2CAP Header|AAAA|  -->  |L2CAP Header|AAAA|  -->  |L2CAP Header|AAAA|
+------------+----+       +------------+----+       +------------+----+

在第二种情况下使用Qt

+------------+------------+
|L2CAP Header|AAAAAAAAAAAA|
+------------+------------+

如何强制Qt套接字的write行为像Python套接字的send

更新:

查看文档,它说

当控制权返回事件循环时写入字节

我如何在返回事件循环之前强制刷新缓冲区?

我如何在返回事件循环之前强制刷新缓冲区?

您不能,因为发送只能异步完成,而不能同步完成。

但是我们可以按照与数据包排队相同的方式排队刷新。 即:发送前一个数据包后发送每个数据包。 因此,每次事件循环处理完所有其他工作时,我们都将发送它。 习惯用法是零持续时间计时器-请注意,这与计时器完全没有关系,这是计时器概念的怪异重载,否则本来就没有任何意义。

int i = 10;
while (i--)
  QTimer::singleShot(0, this, [this]{ m_btSocket.write("<some payload>"); });

m_btSocket必须是该类的成员,并且必须是value成员-否则代码将是不安全的。

如果您希望确保在断开连接的情况下转储过时的数据包并且不会影响任何后续连接,请跟踪它们的生成并仅在当前的情况下发送:

class Foo : public QObject {
  unsigned int m_generation = {}; // unsigned: modulo math w/o overflows
  QBluetoothSocket m_btSocket{QBluetoothServiceInfo::L2CAP};
  ...
  bool isBtConnected() const { return m_btSocket::state() == QBluetoothSocket::ConnectedState; }
  void sendSinglePacket(const QByteArray & data) {
    if (!isBtConnected()) return;
    auto gen = m_generation;
    QTimer::singleShot(0, this, [this, gen, data] {
      if (m_generation == gen)
        m_btSocket.write(data);
    });
  }
  Foo(QObject * parent = {}) : QObject(parent) {
    connect(&m_btSocket, &QBluetoothSocket::Disconnected, this, [this]{
      m_generation++; // drops all in-flight packets
    });
    ...
  }
};

我没有使用QBluetoothSocket的方法找到合适的解决方案,但是我通过一点技巧使其工作。

刚刚使用过的C标头sys/socket.h (我只需要支持POSIX兼容的操作系统)并进行了更改

btSock.write("<some payload>");

send(btSock.socketDescriptor(), "<some payload>", <payload length>);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM