嵌入式学习记录5.18(多点通信)

一、套接字属性设置相关函数

       #include <sys/types.h>          /* See NOTES */#include <sys/socket.h>int getsockopt(int sockfd, int level, int optname,void *optval, socklen_t *optlen);int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t optlen);功能:获取或设置套接字相关层中的相关属性的值参数1:套接字文件描述符参数2:网络层次:应用层:SOL_SOCKET (man 7 socket)传输层(TCP):IPPROTO_TCP (man 7 tcp)传输层(UDP):IPPROTO_UDP (man 7 udp)网络层:IPPROTO_IP (man 7 ip)参数3:当前层要设置或获取的属性名称,每层常设置的名称如下表所示:参数4:要给参数3属性设置的值参数5:参数4的大小返回值:成功返回0,失败返回-1并置位错误码

#include<myhead.h>int main(int argc, const char *argv[])
{//创建套接字int fd = socket(AF_INET, SOCK_DGRAM, 0);if(fd == -1){perror("socket errorr");return -1;}//想要知道当前套接字能否进行端口号和地址的快速重用int reuse = -1;int optlen = sizeof(reuse);if(getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, &optlen) ==-1){perror("getsockopt error");return -1;}printf("reuse = %d\n", reuse);        // 0,表示套接字默认不允许端口号快重用//设置端口号快速重用int optval = 1;if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1){perror("setsockopt error");return -1;}//再次获取套接字属性的值reuse = -1;if(getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, &optlen) ==-1){perror("getsockopt error");return -1;}printf("reuse = %d\n", reuse);        // 1,表示已经设置端口号快速重用了return 0;
}

二、单播

就是实现一对一的通信,我们之前所学的TCP或UDP通信方式都是使用的是单播

发送端和接收端是确定的

三、多点通信

1> 实现主机之间的一对多的通信,一个发送端可以对应多个接收端

2> 对于接收端而言,无论愿不愿意接收,都会收到消息

3> 只能基于UDP实现多点通信

4> 实现多点通信的方式:广播、组播

3.1 广播

1> 能够实现主机的一对多的通信

2> 在当前网络下的所有主机都能接收到广播消息

3> 对于广播的发送端套接字而言,需要将其设置成允许广播的状态

4> 广播地址:网络号 + 255

5> 广播消息不允许穿过路由器

6> 广播分为发送端和接收端

7> 广播的发送端流程----> 类似于UDP的客户端

1、socket:创建用于通信的套接字文件描述符
2、setsockopt:设置当前套接字允许广播, level:SOL_SOCKET      optname:SO_BROADCAST     optval: int
3、bind:可绑定也可以不绑定
4、发送广播消息:sendto目的IP地址:广播地址目的Port:与接收端保持一致
5、close:关闭套接字
#include<myhead.h>
#define IP "192.168.125.255"          //广播地址
#define PORT 6789                    //端口号int main(int argc, const char *argv[])
{//1、创建套接字int sfd = socket(AF_INET, SOCK_DGRAM, 0);if(sfd == -1){perror("socket error");return -1;}//2、设置套接字允许广播int broadcast = 1;if(setsockopt(sfd, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) == -1){perror("setsockopt error");return -1;}//3、发送消息//3.1 填充对端地址信息结构体struct sockaddr_in rin;rin.sin_family = AF_INET;rin.sin_port = htons(PORT);rin.sin_addr.s_addr = inet_addr(IP);char sbuf[128] = "";while(1){//从终端获取数据printf("请输入>>>");fgets(sbuf, sizeof(sbuf), stdin);sbuf[strlen(sbuf)-1] = 0;//将数据广播出去sendto(sfd, sbuf, strlen(sbuf), 0, (struct sockaddr*)&rin, sizeof(rin));printf("发送成功\n");}//4、关闭套接字close(sfd);return 0;
}

8> 广播的接收端流程 ----> 类似于UDP的服务器端

1、socket:创建用于通信的套接字文件描述符 2、bind:必须绑定 IP地址:广播地址 Port:与发送端保持一致 3、recvfrom:接收广播消息 4、close:关闭套接字

#include<myhead.h>
#define IP "192.168.125.255"          //广播地址
#define PORT 6789                    //端口号int main(int argc, const char *argv[])
{//1、创建套接字int rfd = socket(AF_INET, SOCK_DGRAM, 0);if(rfd == -1){perror("socket error");return -1;}//2、绑定ip和端口号//2.1 填充地址信息结构体struct sockaddr_in rin;rin.sin_family = AF_INET;rin.sin_port = htons(PORT);rin.sin_addr.s_addr = inet_addr(IP);//2.2 绑定if(bind(rfd, (struct sockaddr*)&rin, sizeof(rin)) == -1){perror("bind error");return -1;}//3、接受消息char rbuf[128] = "";while(1){bzero(rbuf, sizeof(rbuf));         //清空容器//读取数据recvfrom(rfd, rbuf, sizeof(rbuf), 0, NULL, NULL);//recv(rfd, rbuf, sizeof(rbuf), 0);printf("收到广播消息:%s\n", rbuf);}//4、关闭套接字close(rfd);return 0;
}

3.2 组播

1> 组播也是实现一对多的通信

2> 组播地址:D类网络---> [224.0.0.0 -- 239.255.255.255]

3> 组播也分为发送端和接收端,对于接收端而言,要加入多播组后,才能收到组播消息

4> 组播的发送端 ----> 类似于UDP的客户端

1、socket:创建用于通信的套接字文件描述符
2、bind:可绑定也可以不绑定
3、发送广播消息:sendto目的IP地址:组播地址目的Port:与接收端保持一致
4、close:关闭套接字
#include<myhead.h>int main(int argc, const char *argv[])
{//1、创建套接字int sfd = socket(AF_INET, SOCK_DGRAM, 0);if(sfd == -1){perror("socket error");return -1;}//3、发送消息//3.1 填充对端地址信息结构体struct sockaddr_in rin;rin.sin_family = AF_INET;rin.sin_port = htons(5555);rin.sin_addr.s_addr = inet_addr("224.1.1.1");  //组播地址char sbuf[128] = "";while(1){//从终端获取数据printf("请输入>>>");fgets(sbuf, sizeof(sbuf), stdin);sbuf[strlen(sbuf)-1] = 0;//将数据广播出去sendto(sfd, sbuf, strlen(sbuf), 0, (struct sockaddr*)&rin, sizeof(rin));printf("发送成功\n");}//4、关闭套接字close(sfd);return 0;
}

5> 组播的接收端 ----> 类似于UDP的服务器端

1、socket:创建用于通信的套接字文件描述符
2、setsockopt:将当前套接字加入多播组, level:IPPROTO_IP    optname:IP_ADD_MEMBERSHIP    optval:struct ip_mreqstruct ip_mreqn {struct in_addr imr_multiaddr;    //广播地址struct in_addr imr_address;      //主机ipint            imr_ifindex;      //网卡编号   可以通过指令 ip ad 进行查看当前网卡设备的编号};3、bind:必须绑定IP地址:广播地址Port:与发送端保持一致
4、recvfrom:接收广播消息
5、close:关闭套接字
#include<myhead.h>int main(int argc, const char *argv[])
{//1、创建套接字int rfd = socket(AF_INET, SOCK_DGRAM, 0);if(rfd == -1){perror("socket error");return -1;}//2、加入多播组//2.1 创建结构体变量struct ip_mreqn imq;imq.imr_multiaddr.s_addr = inet_addr("224.1.1.1");    //广播地址imq.imr_address.s_addr = inet_addr("192.168.125.221");  //主机IPimq.imr_ifindex = 2;            //网卡索引//2.2 设置套接字if(setsockopt(rfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imq, sizeof(imq)) == -1){perror("setsockopt error");return -1;}printf("加入多播组成功\n");//3、绑定//3.1 填充地址信息结构体struct sockaddr_in rin;rin.sin_family = AF_INET;rin.sin_port = htons(5555);         //端口号rin.sin_addr.s_addr = inet_addr("224.1.1.1");   //组播IP// 3.3绑定if(bind(rfd, (struct sockaddr*)&rin, sizeof(rin)) == -1){perror("bind  error");return -1;}//4、接受消息char rbuf[128] = "";while(1){bzero(rbuf, sizeof(rbuf));         //清空容器//读取数据recvfrom(rfd, rbuf, sizeof(rbuf), 0, NULL, NULL);//recv(rfd, rbuf, sizeof(rbuf), 0);printf("收到组播消息:%s\n", rbuf);}//5、关闭套接字close(rfd);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/843642.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【PHP小课堂】学习了解PHP中Memcached扩展的使用

学习了解PHP中Memcached扩展的使用 说实话&#xff0c;在目前的开发环境中&#xff0c;使用 Memcache 的项目还真的不多。在 Redis 大行其道的今天&#xff0c;Memcache 的衰退也可以说是大势所趋。不过&#xff0c;可能很多刚开始学习 PHP 的新同学不知道&#xff0c;当年在 L…

【跟着例子学MySQL】多表关联 -- 一对一关系

文章目录 前言回顾一对一关系备份恢复未完待续 前言 举例子&#xff0c;是最简单有效的学习方法。本系列文章以一个贯穿始终的场景&#xff0c;结合多个实例讲解MySQL的基本用法。 ❔ 为什么要写这个系列&#xff1f; 模仿是最好的老师&#xff0c;实践是检验成果的方法。本系…

ABAP 借助公司封装的钉钉URL,封装的RFC给钉钉发送消息

FUNCTION ZRFC_BC_SMSSEND_DINGTALK. *"---------------------------------------------------------------------- *"*"本地接口&#xff1a; *" IMPORTING *" VALUE(DESTUSRID) TYPE CHAR255 *" VALUE(CONTENT) TYPE CHAR255 *&quo…

【论文解读】Modular Blind Video Quality Assessment

原文下载地址:Modular Blind Video Quality Assessment 时间:2024 年 级别:arxiv 作者与机构:香港城市大学、香港中文大学(深圳)、字节跳动公司 git地址:https://github.com/winwinwenwen77/ModularBVQA 摘要 论文提出了一种模块化的盲视频质量评估(Blind Video Quali…

企业如何实现数据采集分析展示一体化

在当今数字化时代&#xff0c;企业越来越依赖于数据的力量来驱动决策和创新。通过全量实时采集各类数据&#xff0c;并利用智能化工具进行信息处理&#xff0c;企业能够借助大数据分析平台深入挖掘数据背后的价值&#xff0c;从而为企业发展注入新动力。 一、企业痛点 随着数字…

使用uniapp编写的微信小程序进行分包

简介&#xff1a; 由于小程序发布的时候每个包最多只能放置2MB的东西&#xff0c;所以把所有的代码资源都放置在一个主包当中不显示&#xff0c;所以就需要进行合理分包&#xff0c;&#xff0c;但是分包后整个小程序最终不能超过20MB。 一般情况下&#xff0c;我习惯将tabba…

Java实现图片保存到pdf的某个位置

Java实现图片保存到pdf的某个位置 1、依赖–maven <dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13</version></dependency>2、上代码 package com.hxlinks.hxiot.controlle…

【OCPP】ocpp1.6协议第3.16章节Metering Data介绍及翻译

目录 3.16. Metering Data计量数据-概述 计量数据的目的 关键功能 消息类型 MeterValues 消息格式 使用场景 计量数据的准确性和可靠性 总结 3.16. Metering Data计量数据-译文 3.16.1. Charging Session Meter Values 3.16.2. Clock-Aligned Meter Values 3.16.3.…

【JavaScript】call、apply、bind的区别和应用

历史小剧场 其实在大多数时间里&#xff0c;除去超人、蝙蝠侠等不可抗力出来维护正义外&#xff0c;邪是经常胜正的。所谓好人、善人、老实人常常被整得凄惨无比&#xff0c;比如于谦、岳飞等&#xff0c;都是死后很多年才翻身平反。 只有岁月的沧桑&#xff0c;才能淘尽一切污…

【Vue】自动导入组件

1. 下载插件 npm install unplugin-vue-components 2. 修改vite.config.js import { fileURLToPath, URL } from node:urlimport { defineConfig } from vite import vue from vitejs/plugin-vue import Components from unplugin-vue-components/vite // 按需加载自定义组件/…

C#中的事件聚合器实现方法

概述&#xff1a;_对象之间的关系_是使代码库难以理解和难以维护的原因。为了更好地理解它&#xff0c;我们求助于马丁福勒&#xff08;Martin Fowler&#xff09;&#xff1a;事件聚合器是间接的简单元素。在最简单的形式中&#xff0c;您可以让它注册到您感兴趣的所有源对象&…

MapStruct与BeanUtils处理对象属性复制场景对比

MapStruct是什么&#xff1f; MapStruct is a code generator that greatly simplifies the implementation of mappings between Java bean types based on a convention over configuration approach. The generated mapping code uses plain method invocations and thus is…

elastich运维

Elastichsearch是一种高度可扩展的开源全文搜索和分析引擎&#xff0c;可以用来实现快速、高效的数据检索。 集群规划与部署&#xff1a;首先需要根据业务需求规划Elastichsearch集群的节点数量和角色&#xff08;如主节点、副本节点、协调节点等&#xff09;。在部署时&#x…

赎金信-力扣

这道题想到的解法是使用一个哈希表来存储magazine里每个字符出现的次数&#xff0c;然后遍历ransomNote&#xff0c;出现对应的字母则哈希表中对应的值减一&#xff0c;当查找不到某个字符&#xff0c;或者某个字符的值小于0时&#xff0c;则返回false。代码如下&#xff1a; …

ORACLE中递归遍历

--查询全部资源信息 select * from urm_class_info --向上遍历树&#xff0c;找到路径直到根节点&#xff0c;指定的是parentid select distinct classid, parentid, namefrom urm_class_infostart with parentid cmdb0000000000000017 connect by prior parentid classid …

配置Spring Security的身份验证

配置Spring Security的身份验证 在我们登录Spring Security之前&#xff0c;我们将向您展示如何配置Spring Security的身份验证。我们将通过创建一些用户来验证并为它们生成身份验证。在这篇文章中&#xff0c;我们将学习Spring Security的流程是配置Spring Security中的身份验…

代码随想录算法训练营第二十一天 | 530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先

530.二叉搜索树的最小绝对差 题目链接&#xff1a;https://leetcode.cn/problems/minimum-absolute-difference-in-bst/ 文档讲解&#xff1a;https://programmercarl.com/0530.%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E7%9A%84%E6%9C%80%E5%B0%8F%E7%BB%9D%E5%AF%B9%E…

VMware Workstation 不可恢复错误:(vmui) 错误代码0xc0000094

软件版本 vmware 17 错误情况 VMware Workstation 不可恢复错误&#xff1a;(vmui) Exception 0xc0000094 has occurred. 问题原因 VMware升级到17.0后&#xff0c;将虚拟机环境的【硬件兼容性】升级至Workstation 17.X后&#xff0c;无法修改设备参数。 解决办法 打开需…

企业营收分析难?搞定收入认领月底不加班!

在当今日益激烈的市场竞争中&#xff0c;企业的营收分析不仅是衡量经营成果的关键指标&#xff0c;更是指导企业未来发展的重要依据。然而&#xff0c;对于许多企业来说&#xff0c;营收分析的过程往往繁琐且耗时&#xff0c;尤其是月底结账时&#xff0c;大量的数据和复杂的计…

【Numpy】NumPy基础入门:创建和管理多维数组

NumPy基础入门&#xff1a;创建和管理多维数组 简介 NumPy&#xff08;Numerical Python的简称&#xff09;是Python语言的一个基础科学计算库&#xff0c;广泛应用于数据分析、机器学习、科学计算和工程领域。NumPy的核心是其强大的N维数组对象ndarray&#xff0c;它为Pytho…