UDP组播
本篇文章,我们将详细介绍如何在W5500芯片上面实现UDP组播(UDP Multicast)通信。并通过实战例程,为大家讲解如何使用UDP组播进行回环测试。
该例程用到的其他网络协议,例如DHCP、UDP,请参考相关章节。有关初始化过程,请参考Network Install章节,这里将不再赘述。
UDP组播简介
UDP组播是一种数据传输方法,允许数据从一个源发送到多个目标设备,加入了相应组播组的接收者都可以接收到数据。这种方式非常高效,广泛应用于需要将相同数据同时传输给多个接收者的场景,如视频流媒体、实时数据分发和大规模软件更新等。IPv4的组播地址范围为 224.0.0.0 到 233.255.255.255。
UDP组播的特点
- 基于UDP协议:UDP是无连接的协议,提供快速、低开销的数据传输,但不保证数据的可靠性、顺序性或重传。UDP组播继承了这些特性, 因此适合对实时性要求高、对可靠性要求较低的场景。
- 高效数据传输: 发送者只需要发送一份数据,网络设备(如路由器、交换机)负责将数据复制并传输到所有组播成员。这种方式节省了带宽,相比单播更高效。
- 不保证可靠性: 数据可能丢失,接收者需要自己处理数据包丢失问题。
- 动态成员管理: 组播组的成员可以动态加入或离开,无需通知发送者。
UDP组播应用场景
接下来,我们了解下在W5500上,可以使用UDP组播完成哪些操作及应用呢?
- 设备发现与自动配置: 实现设备自动发现和网络配置,如智能家居设备通过组播寻找网关或其他设备。
- 实时数据广播: 用于传感器数据分发、工业控制和车联网中实时数据的高效传输。
- 固件更新与配置分发: 对多个设备同时进行固件升级或统一下发配置,减少网络负担。
- 告警和事件通知: 设备异常时实时向多个监控终端广播告警消息。
- 时间同步: 用于局域网内的多设备时间同步,提升协同效率。
- 测试与调试: 设备开发阶段,利用组播收集状态信息和日志数据
UDP组播环回测试工作流程
- 接收方通过IGMP协议加入组播组:IGMP(Internet Group Management Protocol)是一种网络层协议,用于管理主机和路由器间的组播组成员关系。 当接收方希望接收某个组播地址的数据时,会通过IGMP向路由器发送加入组播组的请求。
- 发送方发送测试数据:发送方通过UDP协议将数据包发送到指定的组播地址和端口。所有加入组播组的接收方均可接收到数据包。
- 接收方回传消息: 接收方在接收到组播数据后,主动回传响应消息到该组播组当中。回传的消息可以用于确认发送成功或测试链路的完整性。
UDP单播、组播和广播的区别
以下是UDP单播、组播和广播的区别:

报文解析
UDP协议报文已经在UDP章节中讲解过了,有关这部分的内容请参考相关章节,这里不再赘述。下面我们来讲解一下设备在加入组播时使用的IGMP报文。
IGMP 加入组播组时发送的报文是IGMP Membership Report报文。其格式如下:

字段解释
-
类型 (Type)
值为 0x16(IGMPv2 Membership Report):表示主机请求加入组播组。
值为 0x22(IGMPv3 Membership Report):用于支持 IGMPv3 的精细组播组管理。
-
校验和 (Checksum)
计算方法基于标准的 IP 校验和算法。
用于确保 IGMP 报文的完整性。
-
组地址 (Group Address)
组播组的 IP 地址(范围:224.0.0.0 - 239.255.255.255)。
加入时表示目标的组播地址。
报文示例
|报文原文|
16 00 08 f3 e0 01 01 0b
|报文解析|
Internet Group Management Protocol
[IGMP Version: 2]
Type: Membership Report (0x16) (Type为0x16,表示主机请求加入组播组)
Max Resp Time: 0.0 sec (0x00) (最大响应时间为0)
Checksum: 0x08f3 [correct] (校验和为0x08f3)
[Checksum Status: Good]
Multicast Address: 224.1.1.11 (组地址为224.1.1.11)
实现过程
接下来,我们在W5500上实现UDP 组播回环测试。
UDP通信已经在硬件层面实现,因此我们只需要在主循环中调用udp_multicast()组播功能的函数即可,如下所示:
while (1)
{
udp_multicast(SOCKET_ID, ethernet_buf, Multicast_mac, Multicast_IP, Multicast_port);
}
udp_multicast需要传入5个参数,分别是socket号,socket缓存,组播MAC地址,组播IP地址,组播端口号。 udp_multicast函数内容如下:
int32_t udp_multicast(uint8_t sn, uint8_t *buf, uint8_t *multicast_mac, uint8_t *multicast_ip, uint16_t
multicast_port)
{
int32_t ret;
uint16_t size, sentsize;
uint8_t destip[4];
uint16_t destport, port = 50000;
switch (getSn_SR(sn))
{
case SOCK_UDP:
if ((size = getSn_RX_RSR(sn)) > 0)
{
if (size > DATA_BUF_SIZE) size = DATA_BUF_SIZE;
ret = recvfrom(sn, buf, size, destip, (uint16_t *)&destport);
buf[ret] = 0x00;
printf("recv from [%d.%d.%d.%d][%d]: %s\r\n", destip[0], destip[1], destip[2], destip[3],
destport, buf);
if (ret <= 0)
{
#ifdef _MULTICAST_DEBUG_
printf("%d: recvfrom error. %ld\r\n", sn, ret);
#endif
return ret;
}
size = (uint16_t)ret;
sentsize = 0;
while (sentsize != size)
{
ret = sendto(sn, buf + sentsize, size - sentsize, destip, destport);
if (ret < 0)
{
#ifdef _MULTICAST_DEBUG_
printf("%d: sendto error. %ld\r\n", sn, ret);
#endif
return ret;
}
sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
}
}
break;
case SOCK_CLOSED:
#ifdef _MULTICAST_DEBUG_
printf("%d:Multicast Loopback start\r\n", sn);
#endif
setSn_DIPR(sn, multicast_ip);
setSn_DPORT(sn, multicast_port);
setSn_DHAR(sn, multicast_mac);
if ((ret = socket(sn, Sn_MR_UDP, port, Sn_MR_MULTI)) != sn)
return ret;
#ifdef _MULTICAST_DEBUG_
printf("%d:Opened, UDP组播 Socket\r\n", sn);
printf("%d:Multicast Group IP - %d.%d.%d.%d\r\n", sn, multicast_ip[0], multicast_ip[1],
multicast_ip[2], multicast_ip[3]);
printf("%d:Multicast Group Port - %d\r\n", sn, multicast_port);
#endif
break;
default:
break;
}
return 1;
}
程序进入到udp_multicast函数后会执行一个状态机,根据Socket的状态来执行对应的操作。 当Socket处于SOCK_CLOSED状态时,函数会初始化Socket并加入组播组,然后打印Socket的状态和组播组的信息。
当Socket处于SOCK_UDP状态时,函数会检查是否有数据接收,如果有则将数据打印出来并发送回源地址。函数成功执行后返回1。
运行结果
请注意:
测试实例需要PC端和W5500处于同一网段,且连接的路由器需支持IGMP协议。
烧录例程运行后,首先进行了PHY链路检测,然后是DHCP获取网络地址结果,最后是进行UDP组播回环测试,如下图所示:

接下来,我们将打开一个支持加入 UDP 组播功能的网络调试工具。在使用该工具时,首先要完成必要的配置操作,具体包括设置监听组播和发送消息的相关参数。当完成上述配置后,我们向组播组发送消息,此时可以观察到串口会打印出我们所发送的消息,同时在网络调试工具的组播接收区域会收到相应的回环消息,组播回环测试流程得以正常运行。
请注意:
如果网络调试工具不支持加入组播,会导致收不到回环数据。这里我选的是gitcode上一个开源项目UDP组播调试工具

可以看到组播接收区收到了两条消息,一条是PC端发往组播的消息,一条是回环的消息。
总结
本文介绍了在W5500芯片上实现UDP组播的原理、应用场景及回环测试方法,并通过实战代码展示了其具体实现过程。 下一篇文章将聚焦DNS例程,讲解其工作原理及实现方法,帮助大家更深入地理解网络通信。敬请期待!