QUdpSocket - датаграмма принимается дважды, почему? - PullRequest
0 голосов
/ 01 ноября 2018

Я получаю дейтаграмму дважды на моем QUdpSocket, хотя я наблюдаю за Wireshark, и она принимается только один раз. Я создаю сокет и слушаю порт 11112. Есть другое устройство, которое излучает данные на этот порт, который я слушаю. Я последовательно получаю два сообщения для каждого фактического отправленного сообщения. Я не уверен, что вызывает это. Есть мысли?

Сокращенный код:

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    m_socket = new QUdpSocket(this);
          connect (m_socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onSocketStateChange(QAbstractSocket::SocketState)));
          m_socket->bind(11112, QUdpSocket::ShareAddress);
}

MainWindow::~MainWindow()
{
    delete ui;
    delete m_socket;
}

void MainWindow::readPendingDatagrams()
{
    QByteArray buffer;
    QHostAddress sender;
    quint16 port;

    while(m_socket->hasPendingDatagrams())
    {
        int s = m_socket->pendingDatagramSize();
        buffer.resize(s);
        //for some reason there are two datagrams on the line.
        // I have verified with wireshark that there is only one from the
        // sender so not sure what is happening under the hood...
        m_socket->readDatagram(buffer.data(),buffer.size(),&sender, &port);

        QString source = sender.toString().split(":")[3];
        if (source == "172.20.23.86")
        {
            qInfo() << buffer <<endl;
        }
    }


}

void MainWindow::onSocketStateChange(QAbstractSocket::SocketState state)
{
    if ( state == QAbstractSocket::BoundState ) {
           connect(m_socket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()));
       }

}

1 Ответ

0 голосов
/ 01 ноября 2018

Это может произойти, если дейтаграмма отправляется на широковещательный адрес, и вы привязаны ко всем интерфейсам (0.0.0.0), и есть два интерфейса, на которые принимается дейтаграмма. Чтобы исключить эту возможность, переключитесь на API receiveDatagram и отправьте полную информацию о полученной вами дейтаграмме. Держу пари, что интерфейсы, на которых вы его получаете, будут отличаться каждый раз.

Вы также можете подключить слот readPendingDatagrams потенциально несколько раз, и, следовательно, он может быть запущен несколько раз, хотя hasPendingDatagrams должен возвращать false во второй раз - поэтому, хотя это может быть и не проблема , это проблема a , которую вы должны решить. Он должен быть подключен только один раз - при создании сокета, т. Е. В конструкторе.

...