在Wireshark中看到的数据报,没有被Qt UDP Socket接收

Ben*_*son 6 c++ sockets networking qt udp

我正在编写一个Qt(5.6)应用程序,它通过UDP套接字与FPGA通信.数据包以2 KHz流式传输到PC(所有数据包大小相同,1272字节).Wireshark显示正在发送数据包,UDP标头符合预期.问题是,我使用的Qt UDP套接字从不接收这些数据包.该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;
    }
}
Run Code Online (Sandbox Code Playgroud)
  • UdpConnection不在与main的单独线程上运行.应该是吗?
  • 我绑定成功,我认为"connectToHost"正在工作,因为我能够向远程主机发送消息.
  • 该应用程序已添加到防火墙例外列表中(同样,ARP握手证明它们能够进行通信).
  • 该接口是FPGA和PC之间的直接以太网连接.

为什么Wireshark能够看到这些消息,但我的程序不是?

更新#1 Wireshark将2KHz数据包作为LLC数据包.以太网标头显示正确的目标(我的MAC地址),源地址(在FPGA中硬编码)和长度.IP报头的源IP为192.168.10.200,目标IP为192.168.10.10,UDP报头的源端口为1920,目标端口为1919.

更新#2 Wireshark日志:paste.ee/p/98c1H如您所见,数据包重复并以2KHz从FPGA发送.ARP传输和回复可以作为第5,10和11个数据包找到.

UPDATE#3 传入数据包的IP数据包具有正确的校验和,该校验和未设置为0x0000.

Seb*_*nge 1

该数据包似乎不是有效的 UDP 数据报。

编辑

摆弄数据包后,将以太网标头中的类型更改为 IPv4 (0x0800) 似乎就足够了。

它确实显示了一个奇怪的TTL,值为 0,但这可能与发件人相关。

原帖

为了获得有效的数据报,您应该像这样发送而不是当前的数据:

带 IPv4 的以太网标头(14 字节):(与您的实现相同,但键入 IPv4 0x0800)、源、目标、类型

64006a493488 020826283900 0800
Run Code Online (Sandbox Code Playgroud)

IPv4 标头(20 字节):版本、其他、大小=1298(0512) UDP + 20、Ident、Flags(0x00)、FlagOffset(0)、TTL(128)、协议(17 UDP)、校验和、源 = .10.200 , 目的地 = .10.10

45 00 0512 31f0 00 00 80 11 0000 c0a80ac8 c0a80a0a
Run Code Online (Sandbox Code Playgroud)

UDP 标头(8 字节):源 = 1919,目标 = 1920,长度 = 1278(04fe)= 数据 + 8,示例中未计算校验和 2 字节!!!

077f 0780 003e 9672
Run Code Online (Sandbox Code Playgroud)

DataPayload:1270 字节原始数据

0a9f....
Run Code Online (Sandbox Code Playgroud)

使用它作为数据报,您实际上不应该使用connectToHost(),而应该使用writeDatagram()and 现在可能通过使用and调用信号readyRead()槽来工作。hasPendingDatagrams()readDatagram()