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)
为什么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.
该数据包似乎不是有效的 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()