乐鑫ESP32-C3国产wifi芯片蓝牙mesh组网模块广播功能,什么是广播呢?广播是指将报文发送给网络中所有可能的接收方。广播的用途主要有两个:一个报文就可以通知本地网络中在本地网络中定位一个主机;在本地网络中减少分组流通,一个报文就可以通知本地网络中的所有主机。常见的广播应用报文有:
(1)ARP(Address Resolution Protocol,地址解析协议)。其用途是在本地网络中广播一个 ARP请求“IP 地址为 a.b.c.d 的设备,硬件 MAC 地址是多少,请告诉我”。ARP 的广播属于二层链路层MAC 广播,而不是三层网络层 IP 广播。
(2)DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)。在本地网络中有 DHCI服务器端的前提下,DHCP客户端发送目的IP 地址(通常为 255.255.255.255)的DHCP 请求在同一网络中的 DHCP 服务器端就可以接收到该请求并回复分配的 IP 地址。
广播主要使用 UDP 协议,不适合使用 TCP 协议,TCP 适用于单播。
1.广播地址
对于广播地址,乐鑫ESP32-C3国产wifi芯片蓝牙mesh组网模块可以分为二层链路层 MAC 广播地址 (FF:FF:FF:FF:FF:FF) 和三层网络层IP广播地址(255.255.255.255),以下简称为二层地址、三层地址。本节主要介绍三层地址。一般情况下,在报文的三层地址为全 255 的情况下,二层地址通常也为全 FF。因为三层地址为全255 的报文,意味着本地网络的设备都会收到该报文。如果该报文的二层地址不是全 FF,则该报文在接收设备的二层地址处理中会被丢弃。对于接收设备而言,如果报文的二层地址不是广播地址,也不是本机的 MAC 地址和组播 MAC 地址(如 01:00:5E:XX:XX:XX),就会丢弃不处理。所以一般三层地址是广播地址,二层地址也是广播地址。IPv4地址由子网ID和主机ID 构成,如 地址为 192.168.3.4,子网掩码为 255.255.255.0的设备,其子网 ID 和主机 ID 是通过 IP 地址和子网掩码计算求得的。乐鑫ESP32-C3国产wifi芯片蓝牙mesh组网模块在本例中,子网 ID 是192.168.3.0,主机ID 是4。除了子网ID 和主机D为 255 的情况下是广播地址,只有主机ID是255 的情况下也是广播地址。例如,您有一个 192.168.1/24 的子网,那么 192.168.1.255就是该子网的广播地址。也许有人会有疑问“子网 ID 和主机 ID 全为 255 的广播地址和只有主机ID是255的广播地址有什么区别呢?”全为 255 的广播范围比特定子网的广播范围要大例如,Wi-Fi路由器有两个子网 192.168.1/24 和 192.168.2/24,在子网 192.168.1/24 里的一个主机 192.168.1.2 向目的地址 192.168.1.25 发送报文,Wi-Fi 路由器只会将该报文转给192.168.1/24 子网里的主机,并不会转发给 192.168.2/24 子网里的主机;如果该主机向目的地址255.255.255.255 发送报文,则 Wi-Fi 路由器会将该报文转发给两个子网里的主机。所以这种主机 ID 是 255 的广播地址也称为子网定向广播地址。通过子网定向广播地址可以向指定的子网发送报文,防止局城网中其他不需要接收的子网也收到该报文,避免网络资源浪费。
2.使用 Socket 实现广播发送方
函数 esp send broadeast()实现了向局域网内发送 UDP广播包并且携带数据“Are you Espressif IOT Smart Light”,然后等待对端回复的功能。该函数中用到了伯克利套接字(Ber.Sockets)标准接口,也称为BSD Socket。伯克利套接字是 UNIX 系统中的通用网络接口,不仅支持不同的网络类型,而且也是一种内部进程之间的通信机制。本文乐鑫ESP32-C3国产wifi芯片蓝牙mesh组网模块涉及的 TCP/UDP网编程都使用伯克利套接字,感兴趣的可以阅读人民邮电出版社出版的《UNIX 网络编卷1:套接字联网API》,详细了解伯克利套接字的编程知识,本文只是简单地介绍如何体套接字编程。
本节首先使用 socket(AF_INET,SOCK_DGRAM,0)函数创建 UDP 套接字,然后使用setsockopt()函数开启套接字支持广播,后设置广播的目的地址为全 255、端口为3333,调用 sendto()函数将报文发送出去。可以根据 sendto()函数的返回值判断数据是发送成功。
3.使用 Socket 实现广播接收方
乐鑫ESP32-C3国产wifi芯片蓝牙mesh组网模块函数 esp_receive_broadcast ()实现了广播包的接收与单播回复。与发送方的代码逻辑一样,首先创建 UDP 套接字,并且设置监听的报文源地址和端口号,一般作为服务器端,报文源地址设置为 0.0.0.0,表示不对报文源地址进行验证,调用 bind()函数绑定套接字;然后使用 recvfrom()函数接收报文,当接收到携带了“Are you Espressif IOT Smart Light”数据的广播包后,对端的IP 地址和端口号就保存在 from_addr 里;后以单播的形式将要发送的数据发送给对端。
组播
什么是组播呢? 组播也称为多播,是指将报文发送给那些感兴趣的接收方。相比于单播和广播寻址方案的两个“极端”(要么单个要么全部),组播技术提供了折中的方案。顾名思义,组播主要强调组的概念,也就是说,一个主机可以向一个组地址发送报文,所有加入这个的主机都可以收到报文。这有点类似于子网定向广播,但比子网定向广播更加灵活,因为个组的主机可以随时加入或者离开某个组,这样就可以减轻本地网络与主机的负担。
IGMP (Internet Group Management Protocol,互联网组管理协议)是一种负责IP 组播成员管理的协议,用来在IP 主机和与其直接相邻的组播 Wi-F 路由器之间建立、维护组播组成员关系。对于组播而言,需要 Wi-Fi路由器支持IGMP 协议。
1.组播地址
组播报文目的地址使用D类IP 地址,第一个字节以二进制的 1110 开始,其范围是 224.0.0.0~239.255.255.255。由于组播P 地址标识了一组主机,因此组播IP 地址只能作为目标地址,不能作为源地址,源地址总是单播地址。
乐鑫ESP32-C3国产wifi芯片蓝牙mesh组网模块组播组是一个组,这个组使用特定的组播地址作为标识,组内或者组外的成员往这个组播址发送报文时,由组播地址标识的组内成员就可以收到该报文。组播组可以是永久的,也可以是临时的。在组播地址中,由官方分配的组播地址的称为永久组播组:那些既不是保留址也不是永久组播地址的称为临时组播组。永久组播组和临时组播组内的主机数量都是动的,甚至可以没有主机。
组播地址分类如下:
224.0.0.0~224.0.0.255: 为保留组播地址(永久组播组),地址 224.0.0.0不做分配,其他地址供路由协议使用。
224.0.1.0~224.0.1.255:是公用组播地址,可以用于互联网。
224.0.2.0~238.255.255.255:为用户可用的组播地址(临时组播组),全网范围内有效。239.0.0.0~239.255.255.255:为本地管理组播地址,仅在特定的本地范围内有效。
2.使用 Socket 实现组播发送方
组播发送的实现比广播发送更复杂。组播发送需要设定组播报文的发送接口,如果需要接收某个组播组的报文,还需要加入该组播组。函数 esp_join_multicast_group()实现了组播组发送接口的设置与组播组加入的功能。函数 esp_send_multicast()实现了常规UDP 套接字的创建、绑定、目的地址端口的配置和收发功能。除此之外,还增加了 TTL 的设置,保证该组播组只能在该路由下的局域网中进行。
3.使用 Socket 实现组播接收方
实现组播接收方和实现组播发送方一样,需要指定组播报文的接口和需要加入的组播组。函数esp_recv_multicast()实现了常规 UDP 套接字的创建、绑定、目的地址端口的配置和收发功能。此外,由于本例中还需要发送组播,所以设置了 TTL (Time To Live)。
广播与组播对比
广播与组播的对比所示,从中可以看出来,组播的带宽开销比较小,局域网内的备可以自主加入或者离开感兴趣的或预先规定的组播组来接收和发送数据,比较灵活。对于广播而言,局域网内所有设备都会收到报文,无形中会给局域网内的其他设备增加负担,也会加重局域网带宽的负担。
本地发现之组播应用协议 mDNS
在计算机网络中,乐鑫ESP32-C3国产wifi芯片蓝牙mesh组网模块多播DNS (Multicast DNS,mDNS)协议将主机名解析为不包含本地名称服务器端的小型网络中的IP 地址。这是一种零配置的服务器端,mDNS 与传统域名解析服(DNS) 有着基本相同的编程接口、数据包格式和操作方式。
mDNS 由 Bill Woodcock和 Bill Manning 于 2000 年在IETF 中首次提出,在 2013 年由 StuatCheshire 和 Marc Krochmal 作为标准协议发布在 RFC 6762,并由 Apple Bonjour 和开源Avahi软件包实现,包含在大多数 Linux 发行版中(摘录自维基百科)。
mDNS 是本地网络的域名解析协议,使用 5353 端口,组播地址是 224.0.0.251,是运行于 UDP之上的应用协议。不同于传统的 DNS 协议,mDNS 协议不需要 DNS 服务器端进行域名解析可节省本地网络的域名服务器端配置。
乐鑫ESP32-C3国产wifi芯片蓝牙mesh组网模块启用了mDNS 服务的主机加入局域网后,会首先向局域网的组播地址 224.0.0.251 组播一个息“我是谁,我的IP 地址是多少,我提供的服务和端口号是多少”局域网中其他启用 mDN服务的主机收到该消息后会记录该消息,然后响应“它是谁,它的 P 地址是多少,它提供的服务和端口号是多少”。如果一台主机想要查询 mDNS 域名,会先查询自己的缓存信息,如里没有查询到,则会向局域网组播查询该域名的 IP 是多少,以及提供的服务和端口是多少。如果主机查询一个域名,那么该怎么区分该域名是 DNS 域名还是 mDNS 域名呢? mDNS 域名与DNS 域名是通过后缀.local 区分的。