QUdpSocket теряет силу

У меня есть вопрос относительно QUdpSocket: я получаю сообщения UDP через порт 50011 на многоадресный адрес 239.0.0.1 примерно каждые 0,2 секунды (доказано wireshark).

Следующий код работает хорошо (и печатает «VALID» в каждом сообщении) в течение ~ 1 минуты. После этого messageHandler больше не вызывается сигналом QUdpSocket's readyRead (хотя я дважды проверил с помощью wireshark, и сообщения все еще отправляются).

ServiceDiscovery::ServiceDiscovery(QObject *parent) :
    QObject(parent),
    socket(new QUdpSocket(this))
{
    socket->bind(QHostAddress::AnyIPv4, 50011, QUdpSocket::ShareAddress);
    socket->joinMulticastGroup(QHostAddress("239.0.0.1"));
    connect(socket, &QUdpSocket::readyRead, 
            this, &ServiceDiscovery::messageHandler, 
            Qt::DirectConnection);
}

void ServiceDiscovery::messageHandler()
{
    if(socket->isOpen()) qDebug("OPEN"); // Does not print, ofc.
    if(socket->isReadable()) qDebug("READABLE"); // Does not print.
    if(socket->isValid()) qDebug("VALID"); // Suddenly stops.

    QByteArray datagram;
    while(socket->hasPendingDatagrams()) {
        datagram.resize(socket->pendingDatagramSize());
        socket->readDatagram(datagram.data(), datagram.size());
        Message response(datagram);
        if(response.deserialize()) {
            if(response.getServiceID() == constants::servicediscovery::SERVICE_ID) {
                QByteArray payload = response.getPayload();
                if(payload.size() >= 48) {
                    QString address = QHostAddress(payload.mid(32, 4).toHex().toUInt(nullptr, 16)).toString();
                    quint16 port = payload.mid(38, 2).toHex().toUInt(nullptr, 16);
                    emit found(address, port);
                }
            }
        }
    }
}

Что я здесь делаю неправильно? Заранее спасибо.

РЕДАКТИРОВАТЬ: Из-за комментариев я также вставил обработку дейтаграммы.


person chrizbee    schedule 08.03.2018    source источник
comment
Что, если вы закомментируете код, обрабатывающий дейтаграммы? Возможно, ваша система не в состоянии обработать такое количество запросов (не менее 5 в секунду) или заблокирована.   -  person vahancho    schedule 08.03.2018
comment
@vahancho Я обновил код. «response.deserialize()» формирует QString из дейтаграммы.   -  person chrizbee    schedule 08.03.2018
comment
Извините, под комментарием я имел в виду просто удалить этот код и вообще не обрабатывать дейтаграммы. Это ускорит работу. Если он работает быстрее, он будет обрабатывать больше сообщений. Если вы увидите, что сообщение VALID все еще печатается, это будет признаком того, что ваш код обработки дейтаграмм не может обработать такое количество ожидающих дейтаграмм и просто блокирует цикл обработки событий.   -  person vahancho    schedule 08.03.2018
comment
Я не могу это прокомментировать, так как мое приложение зависит от этого. Но тупик - хорошее предположение. Просто сделать обработчик повторным входом не решит мою проблему, хотя есть проблема с производительностью, которая вызывает это...   -  person chrizbee    schedule 08.03.2018


Ответы (1)


Для записей: у меня была такая же проблема. Причина: демонстрационная библиотека, на которую опирается мое приложение, закрывается после времени оценки не только ее открытых портов, но и всех портов приложения.

person LuckyLuke1984    schedule 03.03.2021