广播组播、本地套接字通信、wireshark、以太网帧格式、三次握手四次挥手

广播(使用 UDP 套接字)

广播地址:主机号最大的地址。
广播:给所在局域网的所有主机发送数据报。(之前的数据报发送方式是单播。)

以下情况中使用广播: 局域网 搜索协议。
比如家中的智能产品, 使用手机可以搜索出附近的智能产品,这就是一个局域网搜索协议。

基于 setsockopt 实现广播

广播发送者(客户端):

1、创建一个数据报套接字;

int sockfd = sock(AF_INET, SOCK_DGRAM, 0); 

2、setsockopt(sockfd, 协议层, 选项名, 数据类型, 大小);

int opt = 1;	// 非0即可 
setsockopt(sockfd, **SOL_SOCKET**, SO_BROADCAST, &opt, sizeof(op)); 

在这里插入图片描述

3、填充结构体;

struct sockaddr_in addr; 
addr.sin_family = AF_INET; 
addr.sin_addr.s_addr = inet_addr(argv[1]); 
addr,sin_port = htons(atoi(argv[2])); 

4、发送数据报;

sendto(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&addr, sizeof(addr));

广播接收者(服务器):

1、创建一个数据报套接字;

int sockfd = socket(AF_INET, SOCK_DGRAM, 0); 

2、绑定广播IP;

struct sockaddr_in saddr, caddr; 
saddr.sin_family = AF_INET; 
saddr.sin_port = htons(atoi(argv[2])); 
saddr.sin_addr.s_addr = inet_addr("0.0.0.0"); 	// 广播地址 或 0.0.0.0 
socklen_t length = sizeof(caddr); 
if (bind(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0){...} 

3、等待接收数据;

recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&caddr, &length); 

缺点:

广播发送给所有主机,过多的的网络会发送大量的网络带宽,造成广播风暴。
广播风暴: 网络长时间被大量数据包占用,无法通信,网络会变得缓慢,甚至崩溃。

机制: 通过向广播地址发送UDP数据包,将数据包发送给网络中的所有主机。当一个主机发送广播消息时,该消息会被路由器转发到网络中的所有子网。然后,每个子网上的主机都会接收到该广播消息,并转发给它们的相邻主机。这个过程会一直持续下去,直到广播消息传播到整个网络中的所有主机,如果这个现象一直循环如此,则会造成广播风暴。

广播:给发送者设定相应的权限;
组播:接收者要加入到多播组;

组播(使用 UDP 套接字)

组播地址(D类IP):224.0.0.1 ~ 239.255.255.255

基于 setsockopt 实现组播

// 多播结构体
struct ip_mreq{struct  in_addr  imr_multiaddr;   // 指定多播组IP struct  in_addr  imr_interface;   // 本地IP,通常指定为 INADDR_ANY--0.0.0.0
}struct in_addr{_be32  s_addr;  					// IP地址(大端)
}

组播接收者(服务器):

1、创建数据报套接字;

int sockfd = sock(AF_INET, SOCK_DGRAM, 0); 

2、加入多播组(仅限于接收者);

// 核心代码 ------------------------------------
struct ip_mreq mreq;			// 定义组播的结构体变量
bzero(&mreq, sizeof(mreq));
mreq.imr_multiaddr.s_addr = inet_addr(argv[1]); 			// 填充多播组IP
mreq.imr_interface.s_addr = inet_addr("0.0.0.0");  			// 自动获取本机IP// 改变套接字属性
setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));

在这里插入图片描述

3、填充结构体,绑定 组播IP 和 端口;

struct sockaddr_in saddr, caddr;
saddr.sin_family = AF_INET; 
saddr.sin_port = htons(atoi(argv[2]));
saddr.sin_addr.s_addr = inet_addr("0.0.0.0"); 			// 组IP
socklen_t length = sizeof(caddr);if (bind(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0){...}

4、等待接收数据;

recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&caddr, &length); 

组播发送者(客户端):

1、创建数据报套接字
2、指定接收方地址为 组播地址,设置端口信息
3、发送数据报

广播和组播的区别:

● 广播方式:将数据报发给所有的主机。过多的广播会占用大量网络带宽,造成广播风暴,影响通信。
● 组播(又称为多播)是一种折中的方式。只有加入某个多播组的主机才能收到数据。
● 组播方式既可以发给多个主机,又能避免像广播那样带来过多的负载。

本地套接字通信

· unix 网络编程:最开始都是一台主机内进程和进程之间的编程。(本地通信)
· socket:可以用于本地间进程通信,创建套接字时使用本地协议 AF_LOCALAF_UNIX

特点:

本地通信不需要IP和端口,无法进行两个主机通信;
分为流式套接字和数据报套接字; // 可以使用 流式套接字 或者 数据包套接字
和其他进程间通信相比,使用方便、效率更高,常用于前、后台进程通信;
unix 域套接字编程,实现本间进程的通信,依赖的是 s 类型的文件;

核心步骤:

#include <sys/socket.h>
#include <sys/un.h>struct sockaddr_un {sa_family_t sun_family;               	/* 本地协议 AF_UNIX */char        sun_path[UNIX_PATH_MAX];  	/* 本地路径 s类型的套接字文件 */
};unix socket = socket(AF_UNIX, type, 0); 	// type 可以为流式套接字或数据包套接字// unix 写为 int 就可以struct sockaddr_un myaddr;
myaddr.sun_family = AF_UNIX; 				// 填充 UNIX 域套接字
strcpy(saddr.sun_path,"./myunix"); 			// 创建套接字的路径

相关代码

receiver
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>
#include <poll.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/time.h>
#include <string.h>int main(int argc, char const *argv[])
{// 1.创建套接字int sockfd = socket(AF_UNIX, SOCK_STREAM, 0);if (sockfd < 0){perror("sock is err:");return -1;}system("rm ./myunix -f");unlink("./myunix");// 2. 填充结构体struct sockaddr_un saddr;saddr.sun_family = AF_UNIX;strcpy(saddr.sun_path, "./myunix");if (bind(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0){perror("bind is err:");    return -1;}if (listen(sockfd,5) < 0){perror("listen is err:");  return -1;}int acceptfd = accept(sockfd, NULL, NULL);if (acceptfd < 0){perror("acceptfd < 0");    return -1;}char buf[128] = "";int recvbyte;while(1){recvbyte = recv(acceptfd, buf, sizeof(buf), 0);if (recvbyte < 0){perror("recv is err:");   return -1;}else if (recvbyte == 0){printf("exit\n");break;}else{printf("buf: %s\n", buf);}}close(sockfd);close(acceptfd);return 0;
}
sender
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>
#include <poll.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/time.h>
#include <string.h>int main(int argc, char const *argv[])
{// 1.创建套接字int sockfd = socket(AF_UNIX, SOCK_STREAM, 0);if (sockfd < 0){perror("sock is err:");return -1;}// 2. 填充结构体struct sockaddr_un saddr;saddr.sun_family = AF_UNIX;strcpy(saddr.sun_path, "./myunix");if (connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0){perror("connect is err:");return -1;}char buf[128] = "";int recvbyte;while(1){fgets(buf,sizeof(buf),stdin);if(buf[strlen(buf) -1] == '\n')buf[strlen(buf) -1] = '\0';send(sockfd, buf, sizeof(buf), 0);}close(sockfd);return 0;
}

网络头协议分析

在这里插入图片描述

wireshark抓包工具

在这里插入图片描述

抓包工具的使用

虚拟机: sudo apt-get install wireshark
windows: 小飞机
(抓包的过程,就是抓取流经网卡的数据。如果不加 sudo 就找不到网卡,没有办法抓到数据。)
两台不同的主机通信 或 两台不同的操作系统(windows、linux)之间 才可以进行抓包。

步骤

1)运行 linux 下的服务器;
在这里插入图片描述

2)打开 windows 下的小飞机;
在这里插入图片描述
在这里插入图片描述

3)打开抓包工具;
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4)过滤无关的包;
在这里插入图片描述

5)小飞机模拟客户端, 与 linux 下的服务器通信;

实现:

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

在这里插入图片描述

包头分析在这里插入图片描述

以太网的完整帧格式

在这里插入图片描述

网络层最大数据帧长度是1500字节。(MTU: 最大传输单元)
链路层最大数据长度是1518字节。(网络层 1500 + 以太网 14 + CRC检错 4)
在这里插入图片描述
在这里插入图片描述

TCP 粘包、拆包 与 UDP丢包

● 发生 TCP 粘包或拆包 有很多原因,常见的有以下几点:
1、待发送数据大于 TCP 发送缓冲区剩余空间大小,将会发生拆包。
2、待发送数据大于 MSS(最大报文长度),TCP 在传输前将进行拆包。
3、待发送数据小于 TCP 发送缓冲区的大小,TCP 将多次写入缓冲区的数据一次发送出去,将会发生粘包。
4、接收数据端的应用层没有及时读取接收缓冲区中的数据,将发生粘包。
● TCP 粘包的 解决办法:
1、发送端给每个数据包添加包首部,首部中应该至少包含数据包的长度,这样接收端在接收到数据后,通过读取包首部的长度字段,便知道每一个数据包的实际长度了。
2、发送端将每个数据包封装为固定长度(不够的可以通过补 \0填充),这样接收端每次从接收缓冲区中读取固定长度的数据就自然而然的把每个数据包拆分开来。
3、可以在数据包之间设置边界,如添加特殊符号,这样,接收端通过这个边界就可以将不同的数据包拆分开。
在这里插入图片描述

以太网头

以太网中封装了 目的mac地址 以及 源mac地址、IP 类型,以太网头又称为 mac头。
切换网络时,IP地址会改变,Mac地址不会改变。
在这里插入图片描述

type 类型
0x0800 ——> 只接收发往 本机MAC 的 IP类型的数据帧;
0x0806 ——> 只接收发往 本机 ARP类型 的数据帧;
0x8035 ——> 只接收发往 本机 RARP类型 的数据帧;
0x0003 ——> 接收发往 本机MAC 的所有类型:IP, ARP, RARP 数据帧,接收从本机发出去的数据帧,
当混杂模式打开的情况下,会接收到非发往本地的 MAC 数据帧。
ARP:ARP协议用于将 IP地址 解析为 MAC地址。当一台计算机向另一台计算机发送数据时,它需要知道目标计算机的 MAC地址,而不是 IP地址。
RARP:RARP协议则是与 ARP 相反的过程,它用于将 MAC地址 解析为 IP地址。

IP头

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

UDP头

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

TCP头

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

三次握手

服务器必须准备好接受外来的连接。这通过调用 socket、 bind 和 listen 函数来完成,称为被动打开(passive open)。
第一次握手:客户通过调用 connect 进行主动打开(active open)。客户端发送一个SYN(表示同步)
分节(SYN=J),它告诉服务器客户将在连接中发送到数据的初始序列号。并进入 SYN_SEND 状态,
等待服务器的确认。
第二次握手:服务器必须确认客户的 SYN,同时自己也得发送一个 SYN 分节,它含有服务器将在同一连接
中发送的数据的初始序列号。服务器以单个字节向客户发送 SYN 和 对客户 SYN 的 ACK(表示确认)
此时服务器进入 SYN_RECV 状态。
第三次握手:客户收到服务器的 SYN+ACK。向服务器发送确认分节,此分节发送完毕,客户服务器进入
ESTABLISHED(确认)状态,完成三次握手。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四次挥手

第一次挥手:主动关闭方发送一个 FIN 给被动方,进入 FIN_WAIT 状态;
第二次挥手:被动方接收到 FIN 包,给主动方发送一个 ACK 包;并进入 CLOSE_WAIT 状态,主动方接收
到 ACK 包后,如果有数据没有发送完毕,则继续发送,一直到发送完毕;
第三次挥手:被动方发送一个 FIN 包,进入 LAST_ACK 状态。
第四次挥手:主动关闭方收到 FIN 包,回复一个 ACK包。被动关闭方收到主动关闭方的 ACK后关闭连接。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

centos7安装MySQL—以MySQL5.7.30为例

centos7安装MySQL—以MySQL5.7.30为例 本文以MySQL5.7.30为例。 官网下载 进入MySQL官网&#xff1a;https://www.mysql.com/ 点击DOWNLOADS 点击链接&#xff1b; 点击如上链接&#xff1a; 选择对应版本&#xff1a; 点击下载。 安装 将下载后的安装包上传到/usr/local下…

Eclipse常用设置-乱码

在用Eclipse进行Java代码开发时&#xff0c;经常会遇到一些问题&#xff0c;记录下来&#xff0c;方便查看。 一、properties文件乱码 常用的配置文件properties里中文的乱码&#xff0c;不利于识别。 处理流程&#xff1a;Window -> Preferences -> General -> Ja…

万宾科技智能井盖传感器效果,特点有哪些?

现在城市发展越来越好&#xff0c;对基础设施的改造越来越多&#xff0c;比如修路搭桥、整改生态等都是为民服务的好工程。平时走在路上我们享受着平整的路面&#xff0c;井然有序的交通也为我们带来很大的方便。但是一个又一个的井盖看起来无关紧要&#xff0c;实际上如果路上…

Linux安装Mysql详细教程(两种安装方法)

Linux之Mysql安装配置 第一种&#xff1a;Linux离线安装Mysql&#xff08;提前手动下载好tar.gz包&#xff09;第二种&#xff1a;通过yum安装配置Mysql&#xff08;服务器有网络&#xff09; 第一种&#xff1a;tar.gz包安装 1、 查看是否已经安装 Mysql rpm -qa | grep m…

论文阅读:MedSegDiff: Medical Image Segmentation with Diffusion Probabilistic Model

论文标题&#xff1a; MedSegDiff: Medical Image Segmentation with Diffusion Probabilistic Model 翻译&#xff1a; MedSegDiff&#xff1a;基于扩散概率模型的医学图像分割 名词解释&#xff1a; 高频分量&#xff08;高频信号&#xff09;对应着图像变化剧烈的部分&…

SqlServer_idea连接问题

问题描述&#xff1a; sqlServer安装之后可以使用navicat进行连接idea使用账户密码进行登录连接失败 问题解决&#xff1a; 先使用sqlServer管理工具进行登录 使用window认证连接修改账户密码 启用该登录名 这时idea还是无法连接&#xff0c;还需要如下配置 打开sqlserve…

机器学习第12天:聚类

文章目录 机器学习专栏 无监督学习介绍 聚类 K-Means 使用方法 实例演示 代码解析 绘制决策边界 本章总结 机器学习专栏 机器学习_Nowl的博客-CSDN博客 无监督学习介绍 某位著名计算机科学家有句话&#xff1a;“如果智能是蛋糕&#xff0c;无监督学习将是蛋糕本体&a…

3D人脸扫描设备助力企业家数字人复刻,打破商业边界

京都薇薇推出数字人VN&#xff0c;以京都薇薇董事长为原型制作&#xff0c;赋能品牌直播、短片宣传、线上面诊等活动&#xff0c;进一步增强消费者对品牌的交互体验&#xff0c;把元宇宙与品牌相融合&#xff0c;推动品牌线上服务与线下服务实现数字一体化&#xff0c;打造一个…

智能座舱架构与芯片- (13) 软件篇 下

四、面向服务的智能座舱软件架构 4.1 面向信号的软件架构 随着汽车电子电气架构向中央计算-域控制器的方向演进&#xff0c;甚至向车云一体化的方向迈进&#xff0c;适用于汽车的软件平台也需要进行相应的进化。 在传统的观念中&#xff0c;座舱域即娱乐域&#xff0c;座舱软…

地埋式积水监测仪厂家直销推荐,致力于积水监测

地埋式积水监测仪是一种高科技设备&#xff0c;能够实时监测地面积水深度&#xff0c;并及时发出预警信息&#xff0c;有效避免因积水而产生的安全隐患。这种智能监测仪可以安装在城市道路、立交桥、地下车库等易积水地势较低的地方&#xff0c;以确保及时监测特殊地段的积水&a…

Spring框架学习 -- 读取和存储Bean对象

目录 &#x1f680;&#x1f680; 回顾 getBean()方法的使用 根据name来获取对象 再谈getBean() (1) 配置扫描路径 (2) 添加注解 ① spring注解简介 ② 对类注解的使用 ③ 注解Bean对象的命名问题 ④ 方法加Bean注解 (3) Bean 注解的重命名 (4) 获取Bean对象 -- …

Linux本地MinIO存储服务远程调用上传文件

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《Linux》《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;…

如何通过类似于Android adb install apk 命令安装三方Harmony Hap包

安装命令 hdc install xxx.hapOpenHarmony设备安装Hap应用的五种方式 https://www.51cto.com/article/762223.htmlhttps://www.51cto.com/article/762223.html DevEco Studio 3.1为例新建个项目&#xff0c;点击File->Project Structure 进入签名页面然后点击Sign in登录华…

基于C#实现赫夫曼树

赫夫曼树又称最优二叉树&#xff0c;也就是带权路径最短的树&#xff0c;对于赫夫曼树&#xff0c;我想大家对它是非常的熟悉&#xff0c;也知道它的应用场景&#xff0c;但是有没有自己亲手写过&#xff0c;这个我就不清楚了&#xff0c;不管以前写没写&#xff0c;这一篇我们…

css animation 动画如何保留动画结束后的状态 animation-fill-mode: forwards

css animation 动画如何保留动画结束后的状态 animation-fill-mode: forwards 一、问题描述 在做一个弹窗动画提示的时候遇到了一个问题&#xff1a; 在动画结束的时候&#xff0c;移除元素时会有闪一下的问题&#xff0c;像这样&#xff0c;有残留的痕迹。 我的动画结尾是这…

Vue3 封装组件库并发布到npm仓库

一、创建 Vue3 TS Vite 项目 输入项目名称&#xff0c;并依次选择需要安装的依赖项 npm create vuelatest 项目目录结构截图如下&#xff1a; 二、编写组件代码、配置项和本地打包测试组件 在项目根目录新建 package 文件夹用于存放组件 &#xff08;以customVideo为例&a…

LeSS敏捷框架高效生产力实践

每个团队可能都有一套适合自己的敏捷方法&#xff0c;本文介绍了ResponseTap工程团队通过采用LeSS框架、引入准备周&#xff0c;从而提升迭代冲刺研发效能的实践。原文: LeSS Agile, More Productive — Part 1: Pain[1], LeSS Agile, More Productive — Part 2: Promise, LeS…

2023亚太杯数学建模APMCM竞赛C题思路讲解:基于ARIMA与机理模型进行预测

本文针对6大问题,从多角度分析了我国新能源电动汽车发展形势与前景。文中针对不同问题,采用了层次分析法、时间序列模型、机理模型、回归模型等数学方法。并结合实例数据,对相关模型进行求解,以量化预测了新能源电动汽车在政策驱动、市场竞争、温室气体减排等多个方面的潜在贡献…

mongo DB -- aggregate分组查询后字段展示

一、分组查询 在mongoDB中可以使用aggregate中的$group操作对集合中的文档进行分组,但是查询后的数据不显示其他字段,只显示分组字段 aggregate进行分组示例 db.collection.aggregate([{$group: {_id: "$field"}},]) 查询后显示 展开只显示两个字段 二、显示所有字段…

找JPG格式图片的地址(持续更新中)

问题描述&#xff1a;找JPG格式图片的地址 解决办法&#xff1a; 第一个 谷歌的images 第二个&#xff0c;搜狗图片和百度图片 不过下载是WEBP格式&#xff0c;可以使用一个在线WEBP格式转JPG格式的在线网站即可。 转换的网址为&#xff1a; https://ezgif.com/webp-to-j…