QUdpSocket环回数据报

时间:2017-09-26 12:45:04

标签: c++ qt sockets udp qt5

我正在使用Qt 5.9而我正在使用双向(发送和接收)QUdpSocket。 如何才能避免在同一个套接字上发送相同的消息?

这是一段代码

//  Socket init
this->UdpSocket->bind( QHostAddress::Any, ARTNET_PROTOCOL_PORT );

connect( this->UdpSocket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()), Qt::UniqueConnection );

[...]

void ArtNetManager::readPendingDatagrams()
{
    QNetworkDatagram networkDatagram;

    qDebug("Udp datagram received");

    while( this->UdpSocket->hasPendingDatagrams() )
    {
        networkDatagram = this->UdpSocket->receiveDatagram();

        qDebug("Received datagram from IP address: %s", networkDatagram.senderAddress().toString().toLatin1().data() );

        this->receiveDatagram( networkDatagram.data() );
    }
}

void ArtNetManager::sendDatagram()
{
    QByteArray ArtNet_RawMsg;

    ArtNet_RawMsg.append( "Test program" );

    //  Writes data on the UDP socket
    qint64 sentBytes = this->UdpSocket->writeDatagram( ArtNet_RawMsg, QHostAddress::Broadcast, ARTNET_PROTOCOL_PORT );

    if( sentBytes == -1 )
    {
        qDebug("Cannot send data on UPD socket. Error: %d", this->UdpSocket->error() );
    }
    else if( sentBytes != ArtNet_RawMsg.size() )
    {
        qDebug("Wrong number of bytes sent. Bytes sent on socket: %d, tx buffer length: %d", sentBytes, ArtNet_RawMsg.size());
    }
}

1 个答案:

答案 0 :(得分:0)

您收到的消息归因于ArtNet行为。 UDP协议通常不会反映传出流量。其他一些ArtNet设备正在这样做。

您可以通过保留一些最近发送的消息的列表并查找它们来忽略这些:

class ArtNetManager : public QObject {
  Q_OBJECT
  int const m_sentFifoLength = 32;
  QList<QByteArray> m_sentFifo;
  ...
}

void ArtNetManager::sendDatagram() {
  sendDatagram({"Test program"});
}

void ArtNetManager::sendDatagram(const QByteArray & msg) {
  if (m_sent_fifo.size() >= m_sentFifoLength))
    fifo.removeLast();
  m_sentFifo.prepend(msg);
  auto bytes = m_udpSocket->writeDatagram(msg, QHostAddress::Broadcast, ARTNET_PROTOCOL_PORT);
  if (bytes != msg.size())
    qWarning() << "can't send datagram" << msg.toHex();
}

void ArtNetManager::readPendingDatagrams() {
  while (m_udpSocket->hasPendingDatagrams()) {
    auto datagram = m_udpSocket->receiveDatagram();
    qDebug() << "received datagram from" << datagram.senderAddress().toString();
    receiveDatagram(datagram.data());
  }
}

void ArtNetManager::receiveDatagram(const QByteArray & msg) {
  auto it = std::find(m_sentFifo.begin(), m_sentFifo.end(), msg);
  if (it != m_sentFifo.end()) {
    m_sentFifo.erase(it);
    return;
  }
  ...
}