嵌入式入门Day36

在这里插入图片描述

多点通信

单播

  1. 单播发生在主机之间一对一的通信模式,交换机或者路由器只对数据进行转发,不做复制
  2. 每次只有两个实体之间进行相互通信,发送端和接收端都是唯一确定的

广播

  1. 主机之间的一对多的通信模式,网络对其中的每一台主机发出的信息都进行复制并转发
  2. 所有主机都可以收到广播消息(无论你是否愿意接收),所以,广播是基于UDP通信模式
  3. 广播地址:网络号 + 255
    例如:主机地址为192.168.125.171 —> 192.168.125.255
  4. 广播消息是不能穿过路由器的,也就是说广播消息禁止在外网上进行传播,所以广播只能完成局域网内的多点通信

广播发送端模型

  1. socket 创建套接字
  2. setsockopt 设置网络属性,允许广播
  3. bind 非必须绑定(绑定的话每次发送端口都是固定的)
  4. 填广播地址信息结构体
    ip:填广播地址(192.168.125.255)
    port:与接收端保持一致
  5. sendto 发送消息
  6. close 关闭套接字

广播的接收端模型

  1. socket 创建套接字
  2. 填充地址信息结构体
    ip:广播地址(192.168.125.255)
    port:与发送端保持一致
  3. bind 绑定端口号与ip地址
  4. recvfrom 接收消息
  5. close 关闭套接字

作业

广播的实现

//发送端
#include <myhead.h>
//广播IP以及端口号
#define BOR_IP "192.168.124.255"
#define BOR_PORT 8888
//自身IP以及端口号
#define IP "192,168.124.112"
#define PORT 6666

int main(int argc, const char *argv[])
{
	//创建套接字
	int socketfd = socket(AF_INET, SOCK_DGRAM, 0);
	if (socketfd == -1)
	{
		perror("socket");
		return -1;
	}
	//允许广播
	int k = 1;
	if ( setsockopt(socketfd, SOL_SOCKET, SO_BROADCAST, &k, sizeof(k)) == -1 )
	{
		perror("setsocketopt");
		return -1;
	}
	printf("成功开启广播\n");
	//绑定自身套接字
	struct sockaddr_in send = {
		.sin_family = AF_INET,
		.sin_port = htons(PORT),
		.sin_addr.s_addr = inet_addr(IP)
	};

	if (bind(socketfd, (struct sockaddr *)&send, sizeof(send)) == -1)
	{
		perror("bind");
		return -1;
	}
	//广播IP等信息
	struct sockaddr_in boradcast = {
		.sin_family = AF_INET,
		.sin_port = htons(BOR_PORT),
		.sin_addr.s_addr = inet_addr(BOR_IP)
	};

	char buff[1024] = "";

	while (1)
	{
		//输入
		fgets(buff, sizeof(buff), stdin);
		buff[strlen(buff) - 1] = '\0';
		//发送到广播地址
		sendto(socketfd, buff, strlen(buff), 0, (struct sockaddr *)&boradcast, sizeof(boradcast));
		if (strcmp(buff, "quit") == 0)
		{
			printf("发送端退出\n");
			break;
		}
		bzero(buff, sizeof(buff));
	} 
	return 0;
}

//接收端
#include <myhead.h>
//广播IP以及端口号
#define IP "192.168.124.255"
#define PORT 8888

int main(int argc, const char *argv[])
{
	//创建套接字
	int socketfd = socket(AF_INET, SOCK_DGRAM, 0);
	if (socketfd == -1)
	{
		perror("socket");
		return -1;
	}
	//广播IP等信息
	struct sockaddr_in recv = {
		.sin_family = AF_INET, 
		.sin_port = htons(PORT),
		.sin_addr.s_addr = inet_addr(IP)
	};
	//绑定广播地址
	if (bind(socketfd, (struct sockaddr *)&recv, sizeof(recv)) == -1)
	{
		perror("bind");
		return -1;
	}

	char buff[1024] = "";
	while (1)
	{
		//接收信息
		recvfrom(socketfd, buff, sizeof(buff), 0,NULL,NULL);
		printf("收到信息:%s\n", buff);
		bzero(buff,sizeof(buff));
	}
	return 0;
}

组播

  1. 组播也是实现主机之间一对多的通信模型,跟广播不同的是,组播发送的消息,只有加入多播组的成员才能收到,没有加入的就无法收到,不会占用柜台的网络带宽
    • 组播也是使用UDP实现
    • 组播地址:就是D类网络,224.0.0.0 – 239.255.255.255

组播的发送端模型

  1. socket 创建套接字
  2. bind 非必须绑定
  3. 填充接收端地址信息结构体
    ip:组播地址,与接收端保持一致(224.0.0.0 – 239.255.255.255)
    port:与接收端保持一致
  4. sendto 发送组播消息
  5. close 关闭套接字

特点:

  1. 发送端发送给组播组IP和端口号
  2. 发送端不需要绑定自己的IP和端口号,只需要发送到组播地址即可

组播接收端模型

  1. socket 创建套接字
  2. setsockopt 设置网络属性(加入多播组)
    设置层级:IPPROTO_IP
    设置属性:IP_ADD_MEMBERSHIP
 struct ip_mreqn {
               struct in_addr imr_multiaddr; /* 组播IP
               struct in_addr imr_address;   /* 本机IP*/
               int            imr_ifindex;   /* 网卡索引 */
           };
  1. 填充地址信息结构体然后bind
    ip:组播IP,与发送端保持一致
    port :与发送端保持一致
  2. 定义发送方结构体,接收发送方信息
  3. recvfrom 接收消息
  4. close 关闭套接字

特点:

  1. 设置允许加入组播组(发送端的IP),设置加入组播组时需要(组播组IP,自己的IP,自己网卡ens33的索引号一般都是2)
  2. 查找自己网卡的索引号:ip addr show或者ip ad
  3. 绑定时绑定的是组播组IP和发送端IP保持一致
  4. 接收端也可以选择不接收发送方信息,recvfron最后两个参数填NULL即可
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值