LWIP应用开发|广播与组播

广播与组播

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的数据包

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Chuangke_Andy/article/details/114272691