无法在Python中接收UDP数据包
我在用Python程序接收从FPGA发送的UDP数据包时遇到了问题。我查看了类似的问题,并做了以下几件事:
- 确认Wireshark可以看到UDP数据包
- 关闭了电脑上的Windows防火墙
- 因为是UDP数据包,所以使用了sock.bind()
- 手动在以太网帧中设置了目标MAC地址,因为FPGA不支持ARP
- 为了测试,将目标IP设置为广播地址10.10.255.255,但没有收到任何数据包
- 将发送方的数据包的UDP校验和设置为0x0000
这是接收端的Python代码:
import socket
import sys
UDP_IP = "10.10.10.87"
UDP_PORT = 4660
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP, UDP_PORT))
print("Socket: "+str(sock.getsockname()))
while True:
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
print(data)
print(addr)
sys.stdout.flush()
当我用另一个Python脚本向10.10.10.87:4660发送数据(来自10.10.10网络中的另一台电脑)时,接收脚本运行得很好。我甚至尝试在FPGA中逐字节重建UDP数据包,使用的是我知道可以正常接收的数据包(不同之处在于源IP、端口和MAC地址,校验和被禁用,标识符也不同)。
这是Wireshark对两个数据包的输出:
Wireshark UDP数据包(左边是Python UDP数据包,正常接收;右边是Xilinx FPGA数据包,Python没有接收到)
我不确定还可以尝试什么。任何帮助都将不胜感激。
1 个回答
2
看起来,FPGA计算出来的IPv4头部的校验和是错误的。这个过程可能会让人感到困惑,因为在路由器跳转时,TTL(生存时间)会发生变化,而新的TTL也会改变IPv4头部,这就意味着每经过一个路由器,校验和都需要重新计算,直到数据包到达接收端的Wireshark。默认情况下,Wireshark是关闭IPv4校验和验证的(在问题的截图中可以看到),如果开启验证,问题就更容易发现了。
在构建数据包时,我把IPv4校验和设置为零(x0000)。在路由器那里,它会被正确地重新计算,并且有了正确的校验和,Python就能接收到这个数据包。
我还测试了一个直接连接(没有路由器)从FPGA到主机电脑的情况。IPv4头部也会被正确地重新计算(我不太确定是在什么地方,可能是在电脑的网卡上?)
希望这些信息对遇到类似问题的人有帮助。