我正在编写一个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;
}
}
为什么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个数据包中找到。
更新#3 传入数据包的IP数据包具有正确的校验和,该校验和未设置为0x0000。
答案 0 :(得分:2)
我对Qt不太熟悉,但对于BSD套接字API,我通常使用bind来设置我的接收端口,但不要使用connect进行UDP连接,尤其是在使用不同的端口时,例如1919 vs 1920 对于套接字API,使用sendto()发送具有目标IP /端口的数据包。
因此,尝试注释掉connectToHost并在发送时直接使用writeDatagram。
答案 1 :(得分:1)
该数据包似乎不是有效的UDP数据报。
修改:
在摆弄数据包之后,似乎足以将以太网标头中的类型更改为IPv4(0x0800)。
确实会显示一个奇怪的 TTL ,其值为0,但这可能与发件人有关。
原帖:
您应该像这样发送有效的数据报,而不是您当前的数据:
带IPv4的以太网标头(14Byte):(在您的实现中,但输入IPv4 0x0800),Source,Dest,Type
64006a493488 020826283900 0800
IPv4-Headers (20Byte):版本,其他,大小= 1298(0512)UDP + 20,标识,标志(0x00),FlagOffset(0),TTL(128),协议( 17 UDP),校验和,来源= .10.200,Dest = .10.10
45 00 0512 31f0 00 00 80 11 0000 c0a80ac8 c0a80a0a
UDP-Header (8Byte):Source = 1919,Dest = 1920,Length = 1278(04fe)= Data + 8,Checksum 2Byte in not calculated in example !!!
077f 0780 003e 9672
DataPayload :1270字节原始数据
0a9f....
使用此作为数据报,您实际上不应该使用connectToHost()
,而是使用writeDatagram()
,现在可能使用信号调用readyRead()
插槽与hasPendingDatagrams()
和readDatagram()
答案 2 :(得分:0)
尝试使用nc并验证从FPGA接收的数据包
nc -lu 192.168.10.10 1920
如果您收到包含nc的数据包,则问题出在您的Qt代码中。您可以在connect的最后一个(可选)参数中尝试Qt :: DirectConnection。也许你阻止当前线程和程序计数器再也不会到达事件循环,因此实际上不会调用任何插槽。