Датаграммы, увиденные в Wireshark, не полученные сокетом Qt UDP

Я пишу приложение Qt (5.6), которое взаимодействует с FPGA через UDP-сокет. Пакеты передаются на ПК с частотой 2 кГц (все пакеты одинакового размера, 1272 байта). Wireshark показывает, что пакеты отправляются, а заголовок UDP соответствует ожиданиям. Проблема в том, что сокет Qt UDP, который я использую, никогда не получает эти пакеты. The readyRead сигнал никогда не называл.

вот фрагмент кода:

UdpConnection::UdpConnection(QObject* parent)
{
    fpgaConnection = QSharedPointer<QUdpSocket>(new QUdpSocket);

    qDebug() << connect(fpgaConnection.data(), &QUdpSocket::readyRead, this, &UdpConnection::readyRead);

    if (fpgaConnection->bind(QHostAddress("192.168.10.10"), 1920))
    {
        qDebug() << "Successfully Bound!";
    }
    else
    {
        qDebug() << "BINDING FAILURE";
    }

    fpgaConnection->connectToHost(QHostAddress("192.168.10.200"), 1919);

    sendArpRequest();
}

void UdpConnection::readyRead()
{
    while (fpgaConnection->hasPendingDatagrams())
    {
        QByteArray buffer;
        buffer.resize(fpgaConnection->pendingDatagramSize());

        QHostAddress sender;
        quint16 senderPort;

        fpgaConnection->readDatagram(buffer.data(), buffer.size(), &sender, &senderPort);
        qDebug() << "Message from:" << sender;
        qDebug() << "Message port:" << senderPort;
        qDebug() << buffer;
    }
}
  • UdpConnection является не работает в отдельном потоке от основного. А должно быть?
  • я успешно связываюсь, и я бы предположил, что "connectToHost" работает, потому что я могу отправить сообщение удаленному хосту.
  • приложение было добавлено в список исключений брандмауэра (опять же, рукопожатие ARP доказывает, что они способны общаться).
  • интерфейс представляет собой прямое ethernet-соединение между FPGA и ПК.

почему Wireshark способен видите эти сообщения, а моя программа нет?

обновление #1 Wireshark имеет пакеты 2KHz как пакеты LLC. Заголовок Ethernet показывает правильное назначение (мой MAC-адрес), адрес источника (жестко закодированный в FPGA) и длину. Заголовок IP имеет IP источника как 192.168.10.200 и IP назначения как 192.168.10.10, заголовок UDP имеет порт источника как 1920 и порт назначения как 1919.

обновление #2 Журналы помощью Wireshark: paste.ee/p/98c1H Как вы можете смотрите, пакет повторяется и отправляется из FPGA на 2 кГц. Передача и ответ ARP можно найти как 5-й, 10-й и 11-й пакет.

обновление #3 IP-пакеты входящих пакетов имеют правильную контрольную сумму, которая не устанавливается в 0x0000.

3 ответов


пакет, похоже, не является действительной Дейтаграммой UDP.

редактировать:

после возни с пакетом, кажется, достаточно изменить тип в заголовке ethernet на IPv4 (0x0800).

он показывает странный TTL со значением 0, но это может быть связано отправителя.

Оригинальное Сообщение:

вместо ваших текущих данных вы должны отправить так, чтобы иметь действительный дейтаграмма:

заголовки Ethernet с IPv4 (14Byte): (как и в вашей реализации, но введите IPv4 0x0800), Source, Dest, введите

64006a493488 020826283900 0800

Адрес IPv4-Заголовка (20байт): версия, другое, Size=1298(0512) UDP + 20, идент., Flags(0x00), FlagOffset(0), TTL(128), протокол (17 UDP), контрольная сумма, Source=.10.200, Dest = .10.10

45 00 0512 31f0 00 00 80 11 0000 c0a80ac8 c0a80a0a

UDP-заголовок (8байт): источник=1919, Dest=1920, длина=1278 (04fe) = данные + 8, контрольная сумма 2Byte не рассчитывается в Примере!!!

077f 0780 003e 9672

DataPayload: 1270 байт необработанных данных

0a9f....

используя это как дейтаграмму, вы на самом деле не должны использовать connectToHost() но использовать writeDatagram() и теперь, вероятно, работает по сигналу вызывается readyRead() гнездо hasPendingDatagrams() и readDatagram().


Я не слишком хорошо знаком с Qt, но для API сокета BSD я обычно использую bind для установки порта приема, но не использую connect для UDP-соединения, особенно при использовании разных портов, таких как ваш 1919 против 1920 Для API сокета используйте sendto () для отправки пакетов с целевым IP/портом.

Итак, попробуйте комментировать connectToHost и напрямую использовать writeDatagram при отправке.


попробуйте с nc и проверьте пакеты, получаемые от FPGA

nc -lu 192.168.10.10 1920

Если у вас есть пакеты с nc, проблема заключается в вашем коде Qt. Вы можете попробовать Qt:: DirectConnection в последнем (необязательном) аргументе connect. возможно, вы блокируете текущий поток, и счетчик программ больше не достигает цикла событий, и поэтому слоты не будут вызываться на самом деле.