无法在 Python 中接收 UDP 数据包

Posted

技术标签:

【中文标题】无法在 Python 中接收 UDP 数据包【英文标题】:Can't receive UDP packet in Python 【发布时间】:2014-12-13 04:35:00 【问题描述】:

我无法在 python 程序中接收从 FPGA 发送的 UDP 数据包。我检查了类似的问题并执行了以下操作:

检查 Wireshark 可以看到 UDP 数据包 在 PC 中禁用 windows 防火墙 使用 sock.bind(),因为它是 UDP 数据包 由于 FPGA 不支持 ARP,因此在以太网帧上手动设置目标 MAC 地址 设置目标 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()

针对发送到 10.10.10.87:4660 的另一个 python 脚本进行测试时 (来自 10.10.10 网络中的另一台 PC)接收器脚本工作正常。我什至尝试从我知道接收正常的数据包中逐字节在 FPGA 中重新创建 UDP 数据包(差异是源 IP、端口和 MAC、校验和(禁用)、标识)。

这是来自 Wireshark 的两个数据包的输出:

Wireshark UDP packet(左边是收到OK的Python UDP数据包,右边是python没有收到的Xilinx FPGA数据包)

我不确定还可以尝试什么。任何帮助将不胜感激。

【问题讨论】:

Aside:将UDP_IP 设置为您的本地地址过于具体。相反,请执行 UDP_IP = '' 绑定到所有接口。这不会解决今天的问题,但可能会防止将来出现问题。 【参考方案1】:

显然,来自 FPGA 计算的 IPv4 标头校验和是错误的。由于 TTL(生存时间)在路由器跃点上发生更改,因此可能会让人感到困惑,并且新的 TTL 也会更改 IPv4 标头,强制每跃点有一个新的校验和,直到它到达接收器端的 Wireshark。默认情况下,Wireshark 禁用 IPv4 校验和验证(如问题截图所示),启用验证后更容易找到答案。

我在数据包构造期间将 IPv4 校验和设置为零 (x0000)。它在路由器上被正确地重新计算,并且使用正确的校验和 Python 可以接收数据包。

我还测试了从 FPGA 到主机 PC 的直接连接(无路由器)。 IPv4 标头也被正确重新计算(我不确定在哪里,可能是 PC 的 NIC?)

希望这对有类似问题的人有用。

【讨论】:

以上是关于无法在 Python 中接收 UDP 数据包的主要内容,如果未能解决你的问题,请参考以下文章

c#,socket无法接收分片的UDP数据包

Unity 游戏内无法接收 UDP 数据包

erlang udp服务器无法接收接受数据包

统一时C#脚本上的UDP服务器启动但无法接收数据包

无法接收使用 GCDAsyncSocket 发送的 UDP 数据包的响应

使用 Qt 获取 UDP 数据并显示成图片