Датаграммы, увиденные в 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. возможно, вы блокируете текущий поток, и счетчик программ больше не достигает цикла событий, и поэтому слоты не будут вызываться на самом деле.