QUdpSocket - датаграмма принимается дважды, почему?

Я получаю дейтаграмму дважды на моем 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()));
       }

}

2 ответа

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

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

Unslander Моника правильная, она привязывается ко всем интерфейсам по умолчанию, исправить можно m_socket->bind(QHostAddress::LocalHost,11112);

Другие вопросы по тегам