2024.12.30(多点通信)

作业:
1、将广播发送和接收端实现一遍,完成一个发送端发送信息,对应多个接收端接收信息实验。

发送端

#include <myhead.h>#define PORT 8888
#define IP "192.168.124.255"int main(int argc, const char *argv[])
{//1、将广播发送和接收端实现一遍,//完成一个发送端发送信息,对应多个接收端接收信息实验。//1.创建套接字int oldfd = socket(AF_INET,SOCK_DGRAM,0);if(oldfd == -1){perror("socket");return -1;}//设置允许广播int k = 11;if(setsockopt(oldfd,SOL_SOCKET,SO_BROADCAST,&k,sizeof(k))==-1){perror("setsockopt");return -1;}printf("允许广播设置成功\n");struct sockaddr_in broadcast = {.sin_family = AF_INET,.sin_port = htons(PORT), 	//发送到该端口.sin_addr.s_addr = inet_addr(IP)};char buff[1024];while(1){fgets(buff,sizeof(buff),stdin);sendto(oldfd,buff,sizeof(buff),0,(struct sockaddr *)&broadcast,sizeof(broadcast));if(strcmp(buff,"quit")==0){printf("发送端退出\n");break;}}close(oldfd);return 0;
}

接收端

#include <myhead.h>
#define PORT 8888
#define IP "192.168.124.255"int main(int argc, const char *argv[])
{//1.创建套接字int oldfd = socket(AF_INET,SOCK_DGRAM,0);if(oldfd == -1){perror("socket");return -1;}//填充广播地址信息结构体struct sockaddr_in send = {.sin_family = AF_INET,.sin_port = htons(PORT),.sin_addr.s_addr = inet_addr(IP)};if(bind(oldfd,(struct sockaddr *)&send,sizeof(send))==-1){perror("bind");return -1;}//接收消息char buff[1024];while(1){recvfrom(oldfd,buff,sizeof(buff),0,NULL,NULL);printf("%s",buff);}return 0;
}

2、使用多线程基于TCP协议的并发执行,一个服务器对应多个客户端实现通信实验。

服务器

#include <myhead.h>
#define PORT 8888
#define IP "192.168.124.123"void *fun(void *fd)
{int newfd = *(int *)fd;char buff[1024];while(1){int res = recv(newfd,buff,sizeof(buff),0);if(res == 0){printf("客户端下线\n");break;}strcat(buff,"霜之哀伤");printf("%s\n",buff);send(newfd,buff,sizeof(buff),0);bzero(buff,sizeof(buff));}//循环结束(客户端下线)子线程退出pthread_exit(NULL); 
}
int main(int argc, const char *argv[])
{//2、使用多线程基于TCP协议的并发执行,//一个服务器对应多个客户端实现通信实验。//1.创建套接字int oldfd = socket(AF_INET,SOCK_STREAM,0);if(oldfd == -1){perror("socket");return -1;}//绑定struct sockaddr_in aaa = {.sin_family = AF_INET,.sin_port = htons(PORT),.sin_addr.s_addr = inet_addr(IP)};if(bind(oldfd,(struct sockaddr *)&aaa,sizeof(aaa))==-1){perror("bind");return -1;}//监听if(listen(oldfd,20)==-1){perror("listen");return -1;}struct sockaddr_in client;int client_len = sizeof(client);pthread_t tid;int newfd;while(1){//接收新客户端连入请求newfd = accept(oldfd,(struct sockaddr *)&client,&client_len);if(newfd == -1){perror("accept");return -1;}//创建子线程与客户端通话if(pthread_create(&tid,NULL,fun,&newfd)==-1){perror("pthread_create");return -1;}}pthread_join(tid,NULL); 	//回收子线程资源close(newfd);close(oldfd);return 0;
}

客户端

#include <myhead.h>
#define IP "192.168.124.123"
#define PORT 8888int main(int argc, const char *argv[])
{//1.创建套接字int oldfd = socket(AF_INET,SOCK_STREAM,0);if(oldfd == -1){perror("socket");return -1;}//连接服务器struct sockaddr_in aaa = {.sin_family = AF_INET,.sin_port = htons(PORT),.sin_addr.s_addr = inet_addr(IP)};if(connect(oldfd,(struct sockaddr *)&aaa,sizeof(aaa))==-1){perror("connect");return -1;}//收发消息char buff[1024];while(1){fgets(buff,sizeof(buff),stdin);buff[strlen(buff)-1] = '\0';send(oldfd,buff,strlen(buff),0);if(strcmp(buff,"quit")==-1){printf("服务器退出成功\n");}bzero(buff,sizeof(buff));recv(oldfd,buff,strlen(buff),0); 		//阻塞接收服务器消息printf("服务器发来消息:%s\n",buff);}return 0;
}

笔记

1、对于套接字而言,在不同的层中,可以设置不同的属性,如端口号快速重用、超时时间、设置广播、加入多播组等等

2、关于网络属性,有两个函数,分别是 setsockopt、getsockopt

        #include <sys/types.h> /* See NOTES */

        #include <sys/socket.h>

        int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);

        功能:获取套接字某些选项的属性。

        参数1:套接字描述符

        参数2:要获取的层级

        参数3:要获取的操作名称

        参数4:获取的值为         0:表示禁用,

                                                非0表示启用。

        参数5:参数4的大小。

        返回值:成功返回0,失败返回-1,并置位错误码

        int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);

        功能:设置套接字某些选项的属性。

        参数1:套接字描述符

        参数2:要设置的层级

        参数3:要设置的操作名称

        参数4:设置的值, 0:表示禁用,

                                        非0表示启用。

        参数5:参数4的大小。

        返回值:成功返回0,失败返回-1,并置位错误码

eg:获取当前端口号是否能快速复用属性:

        int n;

        int len = sizeof(n);

        getsockopt(oldfd,SOL_SOCKET,SO_REUSEADDR,&n,&len);

        如果n==0表示端口号快速复用未启动。

        如果n!=0表示端口号快速复用启动。

        eg:设置当前套接字端口号能快速复用

        int n =999;

        setsockopt(oldfd,SOL_SOCKET,SO_REUSEADDR,&n,sizeof(n));

        启动端口号快速复用功能。

#include <myhead.h>int main(int argc, const char *argv[])
{int oldfd = socket(AF_INET,SOCK_STREAM,0);int n;int len = sizeof(n);getsockopt(oldfd,SOL_SOCKET,SO_REUSEADDR,&n,&len);printf("端口号复用状态:%d\n",n);n = 1;setsockopt(oldfd,SOL_SOCKET,SO_REUSEADDR,&n,sizeof(n));printf("端口号修改为可复用状态后:%d\n",n);return 0;
}

2.单播

1>.单播发生在主机之间一对一的通信模式,交换机或者路由器只对数据进行转发,不做复制

2> 每次只有两个实体之间进行相互通信,发送端和接收端都是唯一确定的

3.广播

1>主机之间的一对多的通信模式,网络对其中的每一台主机发出的信息都进行复制并转发

2>所有主机都可以收到广播消息(无论你是否愿意接收),所以,广播是基于UDP通信模式

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

例如:主机地址为192.168.125.171 ---> 192.168.125.255

4> 广播消息是不能穿过路由器的,也就是说广播消息禁止在外网上进行传播,所以广播只能完成局域网内的多点通信

1、广播的发送端模型 ----> 类似于UDP的客户端

模式

1> socket 创建套接字

2> setsockopt 设置网络属性,允许广播

3> bind 非必须绑定(绑定的话每次发送端口都是固定的)

4> 填广播地址信息结构体

ip:填广播地址(192.168.125.255)

port:与接收端保持一致

5> sendto 发送消息

6> close 关闭套接字

#include <myhead.h>#define PORT 6666
#define IP "192.168.124.255"
int main(int argc, const char *argv[])
{//1、创建套接字int oldfd = socket(AF_INET,SOCK_DGRAM,0);if(oldfd==-1){perror("socket");return -1;}//2、设置允许广播int k = 999;if(setsockopt(oldfd,SOL_SOCKET,SO_BROADCAST,&k,sizeof(k))==-1){perror("setsockopt");return -1;}printf("允许广播设置成功\n");struct sockaddr_in broadcast = {.sin_family = AF_INET,.sin_port = htons(PORT),//发送到该端口.sin_addr.s_addr = inet_addr(IP)};char buff[1024];while(1){fgets(buff,sizeof(buff),stdin);sendto(oldfd,buff,sizeof(buff),0,(struct sockaddr *)&broadcast,sizeof(broadcast));if(strcmp(buff,"quit")==0){printf("发送端退出\n");break;}}close(oldfd);return 0;
}

2、广播的接收端模型 ----> 类似于UDP的服务器端

模式

1> socket 创建套接字

2> 填充地址信息结构体

ip:广播地址(192.168.125.255)

port:与发送端保持一致

3> bind 绑定端口号与ip地址

4> recvfrom 接收消息

5> close 关闭套接字

发送源的负担:广播 > 组播 > 单播

特点:

1、广播地址选取broadcast对应的IP

2、端口号固定

3、发送端不需要绑定固定的IP和端口号,只需要向固定的IP和端口号(广播地址)发送信息即可,

不需要关注谁来接收。

4、接收端必须绑定IP和端口号(广播地址)

5、如果发送端绑定了IP和端口号之后,接收端就无法再次绑定,也无法接收信息。

4、组播(多播)

1、 组播也是实现主机之间一对多的通信模型,跟广播不同的是,组播发送的消息,只有加入多播组的成员才能收到,没有加入的就无法收到,不会占用柜台的网络带宽。

2> 组播也是使用UDP实现。

3> 组播地址:就是D类网络,224.0.0.0 -- 239.255.255.255

2、 组播的发送端模型 --->类似于UDP的客户端

模式

1> socket 创建套接字

2> bind 非必须绑定

3> 填充接收端地址信息结构体

ip:组播地址,与接收端保持一致(224.0.0.0 -- 239.255.255.255)

port:与接收端保持一致

4> sendto 发送组播消息

5> close 关闭套接字

组播发送端:

特点:

1、发送端发送给组播组IP和端口号。

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

#include <myhead.h>
#define PORT 6666
#define IP "192.168.124.172"
int main(int argc, const char *argv[])
{//1、创建套接字int oldfd = socket(AF_INET,SOCK_DGRAM,0);if(oldfd==-1){perror("socket");return -1;}
#if 0//2、绑定struct sockaddr_in send = {.sin_family = AF_INET,.sin_port = htons(PORT),.sin_addr.s_addr = inet_addr(IP)};if(bind(oldfd,(struct sockaddr *)&send,sizeof(send))==-1){perror("bind");return -1;}
#endif//3、发送接收struct sockaddr_in group = {.sin_family = AF_INET,.sin_port = htons(8888),//组播端口号.sin_addr.s_addr = inet_addr("224.1.2.3")//组播IP地址};char buff[1024];while(1){fgets(buff,sizeof(buff),stdin);buff[strlen(buff)-1] = '\0';sendto(oldfd,buff,sizeof(buff),0,(struct sockaddr *)&group,sizeof(group));}return 0;
}

3、组播的接收端模型 ---> 类似于UDP的服务器

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; /* 网卡索引 */ };

3> 填充地址信息结构体然后bind

ip:组播IP,与发送端保持一致

port :与发送端保持一致

4> 定义发送方结构体,接收发送方信息

5> recvfrom 接收消息

6> close 关闭套接字

特点:

1、设置允许加入组播组(发送端的IP),设置加入组播组时需要(组播组IP,自己的IP,自己网卡ens33的索引号一般都是2)

2、查找自己网卡的索引号:ip addr show或者ip ad。

3、绑定时绑定的是组播组IP和发送端IP保持一致。

4、接收端也可以选择不接收发送方信息,recvfron最后两个参数填NULL即可。

#include <myhead.h>
#define ZIP "224.1.2.3"
#define IP "192.168.60.66"
#define PORT 7777
int main(int argc, const char *argv[])
{//1、创建基于UDP的套接字int oldfd = socket(AF_INET,SOCK_DGRAM,0);if(oldfd==-1){perror("socket");return -1;}//2、设置允许加入组播组struct ip_mreqn recv = {.imr_multiaddr.s_addr = inet_addr(ZIP),//组播组IP.imr_address.s_addr = inet_addr(IP),//本机IP.imr_ifindex = 2 //ens33网卡索引号};if(setsockopt(oldfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&recv,sizeof(recv))==-1){perror("setsockopt");return -1;}//3、绑定struct sockaddr_in recv2 = {.sin_family = AF_INET,.sin_port = htons(PORT),.sin_addr.s_addr = inet_addr(ZIP)//绑定组播组IP};if(bind(oldfd,(struct sockaddr *)&recv2,sizeof(recv2))==-1){perror("bind");return -1;}//4、接收信息struct sockaddr_in send;socklen_t send_len = sizeof(send);char buff[1024];while(1){recvfrom(oldfd,buff,sizeof(buff),0,(struct sockaddr *)&send,&send_len);//recvfrom(oldfd,buff,sizeof(buff),0,NULL,NULL);不接收发送方的信息printf("接收到%s发送来的信息:%s\n",inet_ntoa(send.sin_addr),buff);if(strcmp(buff,"quit")==0){printf("接收端也退出\n");break;}}close(oldfd);return 0;
}

思维导图

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

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

相关文章

Python爬虫 - 豆瓣电影排行榜数据爬取、处理与存储

文章目录 前言一、使用版本二、需求分析1. 分析要爬取的内容1.1 分析要爬取的分类1.2 分析要爬取的单个电影的数据1.3 分析如何获取单个电影数据1.3.1 预览数据1.3.2 查看请求网址、方法及请求头信息1.3.3 查看请求参数 2. 数据用途2.1 统计分析2.2 探索性数据分析 (EDA)2.3 高…

爬虫后的数据处理与使用(处理篇)

紧接上文爬虫&#xff0c;我们获取到了一些数据&#xff0c;接下来就是使用和分析了~爬虫阶段式教学——从数据获取到格式化存储&#xff08;附代码与效果图&#xff09;_爬虫网页数据格式化-CSDN博客 为保证数据的正确性和有效性需要对数据进行筛选&#xff0c;保存有效信息&a…

模电面试——设计题及综合分析题0x01(含答案)

1、已知某温控系统的部分电路如下图&#xff08;EDP070252&#xff09;&#xff0c;晶体管VT导通时&#xff0c;继电器J吸合&#xff0c;压缩机M运转制冷&#xff0c;VT截止时&#xff0c;J释放&#xff0c;M停止运转。 &#xff08;1&#xff09;电源刚接通时&#xff0c;晶体…

基于FPGA的2ASK+帧同步系统verilog开发,包含testbench,高斯信道,误码统计,可设置SNR

目录 1.算法仿真效果 2.算法涉及理论知识概要 2.1 2ASK调制解调 2.2 帧同步 3.Verilog核心程序 4.完整算法代码文件获得 1.算法仿真效果 vivado2019.2仿真结果如下&#xff08;完整代码运行后无水印&#xff09;&#xff1a; 设置SNR8db 设置SNR20db 整体波形效果&…

学习笔记:使用 pandas 和 Seaborn 绘制柱状图

学习笔记&#xff1a;使用 pandas 和 Seaborn 绘制柱状图 前言 今天在使用 pandas 对数据进行处理并在 Python 中绘制可视化图表时&#xff0c;遇到了一些关于字体设置和 Seaborn 主题覆盖的小问题。这里将学习到的方法和注意事项做个总结&#xff0c;以便之后的项目中可以快…

【算法day27】动态规划:基础2

题目引用 不同路径不同路径II整数拆分不同的二叉搜索树 1. 不同路径 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Fin…

大数据技术-Hadoop(四)Yarn的介绍与使用

目录 一、Yarn 基本结构 1、Yarn基本结构 2、Yarn的工作机制 二、Yarn常用的命令 三、调度器 1、Capacity Scheduler&#xff08;容量调度器&#xff09; 1.1、特点 1.2、配置 1.2.1、yarn-site.xml 1.2.2、capacity-scheduler.xml 1.3、重启yarn、刷新队列 测试 向hi…

Vscode左大括号不另起一行、注释自动换行

参考大佬的博客VSCode 格式化 cpp 文件时配置左大括号不换行_vscode大括号不换行-CSDN博客 Clang_format_style {BasedOnStyle: Chromium, IndentWidth: 4}

12.30 Redis网络模型基础 IO NIO多路复用

图片引用自黑马程序员redis 网络模型 上图引用自java guide javaguide NIO

基于Qt事件机制中的定时器事件的闹钟设计

目标 代码 pro文件 QT core gui texttospeechgreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c11# The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecated (the exact warnings # depend on …

PawSQL性能巡检平台 (3) - 慢查询采集和优化

在数据库运维管理中&#xff0c;慢查询一直是影响系统性能的重要因素。本文将详细介绍PawSQL数据库性能巡检平台在慢查询管理和优化方面的功能特性&#xff0c;帮助数据库管理员更好地应对性能挑战。 一、PawSQL巡检平台慢查询管理概述 PawSQL平台提供了全面的慢查询管理功能&…

检索增强生成(RAG)的全面综述:演进、当前格局与未来方向

摘要 https://arxiv.org/pdf/2410.12837 本文全面研究了检索增强生成&#xff08;RAG&#xff09;&#xff0c;追溯了其从基础概念到当前最先进技术的演变历程。RAG将检索机制与生成式语言模型相结合&#xff0c;以提高输出的准确性&#xff0c;从而解决了大型语言模型&#…

关于无线AP信道调整的优化(锐捷)

目录 一、信道优化的基本原则二、2.4G频段信道优化三、5G频段信道优化四、信道优化代码具体示例五、其他优化措施 一、信道优化的基本原则 信道优化旨在减少信道间的干扰&#xff0c;提高网络覆盖范围和信号质量。基本原则包括&#xff1a; 1. 选择合适的信道&#xff1a;根据…

拓展C盘内存的方法(C盘旁边不一定是D盘)

问题&#xff1a; 比如&#xff1a;windows现在C盘200GB&#xff0c;D盘600GB&#xff0c;准备额外拓展一个新的盘2TB&#xff0c;如何把新的盘中500GB拓展到C盘中 总结&#xff1a; 通过磁盘管理&#xff1a;如果C盘旁边有未分配空间&#xff0c;可以直接使用“扩展卷”功能…

基于springboot的膳食问答系统的设计与实现

摘 要 本文介绍了一个基于SpringBoot框架的膳食问答系统&#xff0c;该系统融合了文章查看、膳食问答、用户管理、文章管理、知识点管理、系统日志查看、在线用户查看以及办公管理等多项功能。系统采用主流界面设计风格&#xff0c;前端使用HTML构建用户界面&#xff0c;后端则…

如何在LabVIEW中更好地使用ActiveX控件?

在LabVIEW中&#xff0c;ActiveX控件可以帮助实现与其他应用程序或第三方组件的集成&#xff08;例如Microsoft Excel、Word、Internet Explorer等&#xff09;。以下是一些建议&#xff0c;帮助您更好地在LabVIEW中使用ActiveX控件&#xff1a; ​ 1. 理解ActiveX控件的基本原…

使用套接字创建一个服务端,创建一个客户端然后相互通讯

以下是对上述代码的详细解释&#xff1a; #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h>#include <stdio.h> #include <stdlib.h> #include <string.h&…

17.3、网络安全应急响应技术与常见的工具

目录 应急响应常用技术分类信息系统容灾恢复入侵取证过程网络安全应急响应参考案例——阿里云安全应急响应服务阿里云应急响应服务网络安全应急响应参考案例—永恒之蓝Wannacry 应急响应常用技术分类 一共五个类别&#xff0c;访问控制、安全评估系统&#xff0c;恢复、安全监测…

MySQL系列之数据类型(String)

导览 前言一、字符串类型知多少 1. 类型说明2. 字符和字节的转换 二、字符串类型的异同 1. CHAR & VARCHAR2. BINARY & VARBINARY3. BLOB & TEXT4. ENUM & SET 结语精彩回放 前言 MySQL数据类型第三弹闪亮登场&#xff0c;欢迎关注O。 本篇博主开始谈谈MySQ…

Ubuntu24.04最新版本安装详细教程

Ubuntu 24.04 LTS发布说明 推荐的系统配置要求&#xff1a; 双核2 GHz处理器或更高 4 GB系统内存 25 GB磁盘存储空间 可访问的互联网 光驱或USB安装介质 Ubuntu 24.04官方下载网址&#xff1a;https://cn.ubuntu.com/download/desktop 04. Ubuntu 22.04(创建虚拟机方式一) 4…