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

news2024/11/15 16:37:48

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

       #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_mreq
                 struct ip_mreqn {
                               struct in_addr imr_multiaddr;    //广播地址
                               struct in_addr imr_address;      //主机ip
                               int            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");  //主机IP
    imq.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.coloradmin.cn/o/1706070.html

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

相关文章

Python批量docx或doc文档转换pdf

说明&#xff1a; 1、因为项目需要&#xff0c;需要手动将十几个word文档转换成pdf文档 2、python请安装3.9.0以上&#xff0c;否则一些依赖库无法正常用 #! /usr/bin/python3 # -*- coding: utf-8 -*-import os import comtypes.client# 批量将docx文件转换pdf文件 def docx_t…

1109 擅长C(测试点0,1,2,3)

当你被面试官要求用 C 写一个“Hello World”时&#xff0c;有本事像下图显示的那样写一个出来吗&#xff1f; ..C.. .C.C. C...C CCCCC C...C C...C C...C CCCC. C...C C...C CCCC. C...C C...C CCCC. .CCC. C...C C.... C.... C.... C...C .CCC. CCCC. C...C C...C C...C C…

【马蹄集】— 百度之星 2023

BD202301公园 可以先 b f s bfs bfs统计一下 t , f t,f t,f到达每个点的距离&#xff0c;还有 n n n到达其他点的距离即其他点到达 n n n的距离 然后枚举每个点 直接计算得到最小值即可 注意特判有人无法到达 n n n的情况 code: #include<bits/stdc.h> #define endl \n…

品牌做电商控价的原因

品牌控价确实是一项至关重要的任务&#xff0c;它关乎着品牌形象、市场定位以及长期发展的稳定性。在电商平台上&#xff0c;价格的公开性和透明度使得消费者、经销商和其他渠道参与方都能够轻易地进行价格比较。因此&#xff0c;品牌方必须对电商渠道的价格进行严格的管控&…

电商API接口助力直播带货选品||助力电商平台搭建选品

如今&#xff0c;直播带货如火如荼。直播带货的核心是卖货、品牌盈利&#xff0c;那想要带货效果更好&#xff0c;选品及定价是最关键的环节。 事实上&#xff0c;品牌企业可以直接使用API接口工具来辅助自身选品及定价&#xff0c;这主要是因为比价工具在直播带货选品环节能起…

因智而兴 向“新”而行 | 软通动力携子公司鸿湖万联亮相数字中国建设峰会·智算云生态大会

5月23日至27日&#xff0c;第七届数字中国建设峰会在福州盛大召开。作为峰会的重要组成部分&#xff0c;由中国电信、中国电科、中国电子联合主办的第三届智算云生态大会同步召开。此次大会以“国云注智 聚力向新”为主题&#xff0c;深入探讨了智算云、人工智能、数据要素、量…

干货!渗透测试入门教程!(建议收藏)

渗透测试是指从内网、外网等网络环境中&#xff0c;利用各种手段对某个特定网络进行模拟攻击&#xff0c;目的是为了寻找可能被利用的漏洞&#xff0c;是企业中重要的一环、 虽然大多数人在学习后都能快速上手&#xff0c;但渗透测试还是有一定的门槛&#xff0c;今天就给大家…

电脑重要文件如何加密保护?教你两种方法

加密是保护电脑重要文件的常见方法&#xff0c;可以有效避免文件数据泄露。那么&#xff0c;电脑重要文件该如何加密保护呢&#xff1f;下面小编就来教你两种方法&#xff0c;帮助你解决文件安全问题。 超级加密3000 超级加密3000是一款专业的电脑数据加密软件&#xff0c;可以…

自定义CSS属性(@property)解决自定义CSS变量无法实现过渡效果的问题

且看下面的代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>demot</title&g…

幼儿园老师投稿渠道

幼儿园老师投稿通常指的是教师为了分享自己的教学经验、教育活动设计、儿童发展研究等内容&#xff0c;向专业杂志、教育平台或在线论坛提交文章或资料的过程。以下是一些关于幼儿园老师投稿的步骤和建议&#xff1a; 一、准备工作 选择合适的平台 研究不同平台的读者群体&a…

大连瓦房店市科工局副局长乔宽一行调研蓝卓

日前&#xff0c;瓦房店市科技和工业信息化局副局长乔宽、副局长国海军、轴承协会秘书长高钧一行莅临蓝卓调研&#xff0c;学习浙江数字经济发展路径&#xff0c;考察蓝卓数字化服务能力。蓝卓副总经理陈挺、装备汽配军团总监陈伟亮、数字化咨询总监周立斌、大连区域方案经理龚…

手机信息恢复:应对数据丢失的策略与技术

由于各种原因&#xff0c;我们经常会遭遇到手机数据丢失的困境。如何有效地应对数据丢失&#xff0c;找回那些对我们来说至关重要的信息&#xff1f;这就需要我们了解和掌握手机信息恢复的策略与技巧。本文将为您揭示信息数据恢复的奥秘&#xff0c;介绍应对数据丢失的实用方法…

视频号小店脱颖而出,一跃成为电商黑马!马化腾要实现电商梦了?

大家好&#xff0c;我是喷火龙。 视频号这个名字在电商的圈子里是经常被提起的&#xff0c;特别是从今年开始&#xff0c;很多之前的电商项目不行&#xff0c;加上传统电商平台开始走下坡路&#xff0c;于是很多电商人都把视频号小店作为一个新的突破口。 因为视频号小店足够…

mySQL事务、存储引擎

什么是事务&#xff0c;事务特性————>保证数据完整性 1,事务是作为单个逻辑工作单元执行的一些列操作。 2,多个操作为一个整体向系统提交&#xff0c;要么执行&#xff0c;要么都不执行。 3,事务是一个不可分割的工作逻辑单元。 事务四特性&#xff1a; 原子性atomi…

假如有几十个请求,如何去控制高并发?

公司项目中做图片或文件批量下载&#xff0c;每次下载都是大批量的&#xff0c;那么假如我一次性下载几十个&#xff0c;如何去控制并发请求的&#xff1f; 让我想想&#xff0c;额~&#xff0c; 选中ID&#xff0c;循环请求&#xff1f;&#xff0c;八嘎&#xff01;肯定不是那…

【数据结构】 排序算法 ~ 总结篇

文章目录 1. 排序几个重点概念的理解2. 排序算法的分析&#x1f427; 1. 排序几个重点概念的理解 2. 排序算法的分析&#x1f427;

C语言中的位段

位段是通过结构体实现的&#xff0c;可以在一定程度上减小空间浪费&#xff0c;位段的声明和结构体类似&#xff0c;有以下几个不同&#xff1a; ①位段的成员必须是整形&#xff08;int,char,short等&#xff09;。 ②成员后边有冒号和数字&#xff0c;表示该成员占几个bit位…

Zigbee +PC上位机 无线控制二维云台开发笔记

今日尝试开发一款简单好学的PC上位机无线控制二维云台的小试验品&#xff1a; 主要开发环境与工具介绍&#xff1a; 单片机 STM32F103C8T6 使用标准库函数编程 Visual Studio 2022软件C# Winform 开发 上位机控制软件 DL_20 无线串口模块 &#xff0b; USB-TTL 模块 实现无线通…

tty/pty/console/getty/shell/telnet

tty 终端(termimal)= tty(Teletypewriter, 电传打印机),作用是提供一个命令的输入输出环境,在linux下使用组合键ctrl+alt+T打开的就是终端,可以认为terminal和tty是同义词。 tty泛指所有的终端设置,这些是真实存在的设备。 通过tty命令可以查看当前终端连接的设备。…

水电智能抄表是什么?

1.简述&#xff1a;水电智能抄表的兴起 水电智能抄表系统是现代科学技术和传统公共文化服务相结合的产物&#xff0c;它通过自动化技术性改变了传统的人工抄表方式&#xff0c;大大提高了高效率&#xff0c;降低生产成本&#xff0c;同时也为用户提供了更为贴心的服务。这一新…