LWIP应用开发|广播与组播
广播与组播1. 广播与组播简介1.1 组网方式网络中有三种通讯模式:单播、广播、组播(多播)单播:主机之间“一对一”的通讯模式,网络中的交换机和路由器对数据只进行转发不进行复制。如果10个客户机需要相同的数据,则服务器需要逐一传送,重复10次相同的工作。网络中的路由器和交换机根据其目标地址选择传输路径,将IP单播数据传送到其指定的目的地广播:主机之间“一对所有”的通讯模式,网络对其中每一台主机发出
广播与组播
1. 广播与组播简介
1.1 组网方式
网络中有三种通讯模式:单播、广播、组播(多播)
- 单播:主机之间“一对一”的通讯模式,网络中的交换机和路由器对数据只进行转发不进行复制。如果10个客户机需要相同的数据,则服务器需要逐一传送,重复10次相同的工作。网络中的路由器和交换机根据其目标地址选择传输路径,将IP单播数据传送到其指定的目的地
- 广播:主机之间“一对所有”的通讯模式,网络对其中每一台主机发出的信号都进行无条件复制并转发,所有主机都可以接收到所有信息(不管你是否需要)。在数据网络中广播被限制在二层交换机的局域网范围内,禁止广播数据穿过路由器,防止广播数据影响大面积的主机(广播风暴)
- 组播:主机之间“一对一组”的通讯模式,即加入了同一个组的主机可以接受到此组内的所有数据,网络中的交换机和路由器只向有需求者复制并转发其所需数据。主机可以向路由器请求加入或退出某个组,网络中的路由器和交换机有选择的复制并传输数据,即只将组内数据传输给那些加入组的主机。这样既能一次将数据传输给多个有需要(加入组)的主机,又能保证不影响其他不需要(未加入组)的主机的其他通讯
1.2 IP地址
广播IP地址:包括全网和局域网广播地址两种
- 全网广播地址
//全网广播地址
255.255.255.255
- 局域网广播地址
/******************************/
C 类地址: 192.168.1.0
子网掩码: 255.255.255.0
段内广播地址:192.168.1.255
/******************************/
B 类地址: 172.16.0.0
子网掩码: 255.255.0.0
段内广播地址:172.16.255.255
/******************************/
A 类地址: 10.0.0.0
子网掩码: 255.0.0.0
段内广播地址:10.255.255.255
/******************************/
组播IP地址:IP组播地址用于标识一个IP组播组。IANA把D类地址空间分配给组播使用,范围从224.0.0.0到239.255.255.255
2. 广播和组播实现
参考Socket API编程优化一文,在该文的工程源码基础上添加代码,来实现广播和组播功能
首先使能LWIP_IGMP宏开关
//opt.h文件中使能LWIP_IGMP
#if !defined LWIP_IGMP || defined __DOXYGEN__
#define LWIP_IGMP 1
#endif
2.1 广播实现
在工程中创建boradcast.c和对应的头文件,编写广播任务函数并将其添加到freertos任务中即可
#include "boradcast.h"
#include "socket_tcp_server.h"
#include "socket_wrap.h"
#include "ctype.h"
#include "string.h"
#include "FreeRTOS.h"
#include "task.h"
void vBoradcastTask(void){
int sfd;
struct sockaddr_in client_addr;
socklen_t client_addr_len;
int optval = 1;
//创建socket udp通信
sfd = Socket(AF_INET, SOCK_DGRAM, 0);
setsockopt(sfd, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(optval));
client_addr.sin_family = AF_INET;
client_addr.sin_port = htons(SERVER_PORT);
client_addr.sin_addr.s_addr = inet_addr("255.255.255.255");
client_addr_len = sizeof(client_addr);
while(1){
//发送广播数据
Sendto(sfd, "broadcast data", strlen("broadcast data"), 0, (struct sockaddr *)&client_addr, client_addr_len);
vTaskDelay(5000);
}
}
2.2 组播实现
在工程中创建multicast.c和对应的头文件,编写组播任务函数并将其添加到freertos任务中即可
#include "multicast.h"
#include "socket_tcp_server.h"
#include "socket_wrap.h"
#include "ctype.h"
#include "string.h"
#include "FreeRTOS.h"
#include "task.h"
void vMulticastTask(void){
int sfd;
struct sockaddr_in client_addr;
socklen_t client_addr_len;
ip_mreq multicast_mreq;
//填充组播地址信息
multicast_mreq.imr_multiaddr.s_addr = inet_addr("224.0.1.1");
multicast_mreq.imr_interface.s_addr = htonl(INADDR_ANY);
//创建socket udp通信
sfd = Socket(AF_INET, SOCK_DGRAM, 0);
//设置组播选项
setsockopt(sfd, IPPROTO_IP, IP_MULTICAST_IF, &multicast_mreq, sizeof(multicast_mreq));
client_addr.sin_family = AF_INET;
client_addr.sin_port = htons(SERVER_PORT);
client_addr.sin_addr.s_addr = inet_addr("224.0.1.1"); //组播ip
client_addr_len = sizeof(client_addr);
while(1){
//发送广播数据
Sendto(sfd, "multicast data", strlen("multicast data"), 0, (struct sockaddr *)&client_addr, client_addr_len);
vTaskDelay(5000);
}
}
3. wireshark抓包验证
wireshark抓包工具获取:wireshark下载地址
wireshark的使用流程:选择网卡 → 配置过滤器
wireshark过滤器配置方法:
比较运算符
eq, == Equal
ne, != Not Equal
gt, > Greater Than
lt, < Less Than
ge, >= Greater than or Equal to
le, <= Less than or Equal to
协议字段
#以太网过滤
eth.dst eq ff:ff:ff:ff:ff:ff
#IP地址过滤
ip.dst eq 192.168.1.10
ip.src == 192.168.1.1
#TCP过滤
tcp.port == 6666
# UDP过滤
udp.port == 6666
# http过滤
http.request.method == "POST"
位域操作
# TCP SYN
tcp.flags & 0x02
逻辑表达式
and, && Logical AND
or, || Logical OR
not, ! Logical NOT
# tcp.port == 80 and ip.src == 192.168.2.1
将上一章节中的广播和组播代码分别编译下载到开发板后,使用wireshark抓包进行验证
- 选择网卡
- 配置过滤器:udp.port == 6666 抓取端口6666的数据包
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)