广播组播、本地套接字通信、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后关闭连接。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android进阶知识:ANR的定位与解决

1、前言 ANR对于Android开发者来说一定不会陌生&#xff0c;从刚开始学习Android时的一不注意就ANR&#xff0c;到后来知道主线程不能进行耗时操作注意到这点后&#xff0c;程序出现ANR的情况就大大减少了&#xff0c;甚至于消失了。那么真的是只要在主线程做耗时操作就会产生…

分类预测 | Matlab实现基于DBN-SVM深度置信网络-支持向量机的数据分类预测

分类预测 | Matlab实现基于DBN-SVM深度置信网络-支持向量机的数据分类预测 目录 分类预测 | Matlab实现基于DBN-SVM深度置信网络-支持向量机的数据分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.利用DBN进行特征提取&#xff0c;将提取后的特征放入SVM进行分类…

【Java 进阶篇】从Java对象到JSON:Jackson的魔法之旅

在现代的软件开发中&#xff0c;处理数据的能力是至关重要的。而当我们谈及数据格式时&#xff0c;JSON&#xff08;JavaScript Object Notation&#xff09;通常是首选。为了在Java中轻松地将对象转换为JSON&#xff0c;我们需要一种强大而灵活的工具。这时&#xff0c;Jackso…

uniapp实现表单弹窗

uni.showModal({title: 删除账户,confirmColor:#3A3A3A,cancelColor:#999999,confirmText:确定,editable:true,//显示content:请输入“delete”删除账户,success: function (res) {console.log(res)if(res.confirm){if(res.contentdelete){console.log(123123123213)uni.setSto…

Spark---集群搭建

Standalone集群搭建与Spark on Yarn配置 1、Standalone Standalone集群是Spark自带的资源调度框架&#xff0c;支持分布式搭建&#xff0c;这里建议搭建Standalone节点数为3台&#xff0c;1台master节点&#xff0c;2台worker节点&#xff0c;这虚拟机中每台节点的内存至少给…

关于 win11 系统下12代/13代英特尔大小核架构 CPU 的 VMware 优化:输入延迟、卡顿,大小核调度

关于 win11 系统下12代/13代英特尔大小核架构 CPU 的 VMware 优化&#xff1a;输入延迟、卡顿&#xff0c;大小核调度 一、前言二、VMware 的优化2.1 键鼠输入延迟问题的解决2.1.1 搜索内核隔离2.1.2 关闭内存完整性并重启2.1.3 搜索启用或关闭windows功能2.1.4 关闭 hyper-v 和…

利用 Apache Ranger 管理 Amazon EMR 中的数据权限

需求背景简介 系统安全通常包括两个核心主题&#xff1a;身份验证和授权。一个解决“用户是谁”的问题&#xff0c;另一个解决“用户允许执行什么操作”的问题。在大数据领域&#xff0c;Apache Ranger 是最受欢迎的授权选择之一&#xff0c;它支持所有主流大数据组件&#xff…

联想拯救者Lenovo Legion R9000K 2021H(82N6)原装出厂Windows10/Win11系统ISO镜像

链接&#xff1a;https://pan.baidu.com/s/13NkeCXNdV0Ib5eeRnZUeAQ?pwdnlr7 提取码&#xff1a;nlr7 拯救者笔记本电脑原厂WIN系统自带所有驱动、出厂主题壁纸、系统属性专属LOGO标志、Office办公软件、联想电脑管家等预装程序 所需要工具&#xff1a;16G或以上的U盘 文…

关于Flink的旁路缓存与异步操作

1. 旁路缓存 1. 什么是旁路缓存? 将数据库中的数据,比较经常访问的数据,保存起来,以减少和硬盘数据库的交互 比如: 我们使用mysql时 经常查询一个表 , 而这个表又一般不会变化,就可以放在内存中,查找时直接对内存进行查找,而不需要再和mysql交互 2. 旁路缓存例子使用 dim层…

基于JavaWeb+SSM+Vue教学辅助微信小程序系统的设计和实现

基于JavaWebSSMVue教学辅助微信小程序系统的设计和实现 源码获取入口前言主要技术系统设计功能截图Lun文目录订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码获取入口 前言 1.1 概述 随着信息时代的快速发展&#xff0c;互联网的优势和普及&#xff0c;人们生活…

HCIP-四、MUX-vlanSuper-vlan+端口安全

四、MUX-vlan&Super-vlan端口安全 MUX-vlan实验拓扑实验需求及解法1. 在SW1/2/3分别创建vlan10 20 30 402. SW1/2/3之间使用trunk链路&#xff0c;仅允许vlan10 20 30 40 通过。3. SW与PC/Server之间使用access链路。4. ping验证&#xff1a; Super-vlan端口安全实验拓扑实…

汽车级芯片NCV7518MWATXG 可编程六沟道低压侧 MOSFET预驱动器 特点、参数及应用

NCV7518MWATXG 可编程六沟道低压侧 MOSFET 预驱动器属于 FLEXMOS™ 汽车级产品&#xff0c;用于驱动逻辑电平 MOSFET。该产品可通过串行 SPI 和并行输入组合控制。该器件提供 3.3 V/5 V 兼容输入&#xff0c;并且串行输出驱动器可以采用 3.3 V 或 5 V 供电。内部通电重置提供受…

助力企业前行——ScalaSpark最佳实践课程

时间飞逝&#xff0c;转眼间我们的Scala&Spark培训课程已经圆满结束&#xff01;在这段精彩的学习旅程中&#xff0c;你们展现了坚韧、决心和追求卓越的品质。 scala(Scalable Language)是一种多范式的编程语言&#xff0c;其设计的初衷是要集成面向对象编程和函数式编程的…

【机器学习】On the Identifiability of Nonlinear ICA: Sparsity and Beyond

前言 本文是对On the Identifiability of Nonlinear ICA: Sparsity and Beyond (NIPS 2022)中两个结构稀疏假设的总结。原文链接在Reference中。 什么是ICA(Independent component analysis)&#xff1f; 独立成分分析简单来说&#xff0c;就是给定很多的样本X&#xff0c;通…

Linux基础命令3

移动&#xff0c;剪切文件 普通文件的移动剪切 现在在这儿 上图中&#xff0c;mv y.x ./tmp的意思&#xff0c;就是将当前路径下的y.x文件进行剪切&#xff0c;然后放到路径为当前路径下的tmp目录文件夹里面 操作完成后可以cd tmp&#xff0c;ls看到y.x文件已经在里面了 现在…

CUTLASS 1.3.3中的 Volta884_h884gemm

CUTLASS 是 CUDA C 模板抽象的集合&#xff0c;用于在 CUDA 内的所有级别和规模上实现高性能矩阵-矩阵乘法 (GEMM) 和相关计算。它采用了类似于 cuBLAS 和 cuDNN 中实现的分层分解和数据移动策略。 CUTLASS 最新版本为3.3&#xff0c;相比1.3.3变动较大。然而重温一下1.3.3仍然…

Django 创建项目时找不到数据库sqlite3

原因:PyCharm创建Django项目,找不到数据库sqlite3 解决&#xff1a;如果没有默认的db文件&#xff0c;则应在PyCharm终端中执行以下命令&#xff1a; python manage.py makemigrations python manage.py migrate

实现点击一个选框 使得一个组件的可选性修改

实现效果 代码 html <div class"divrow"><el-checkbox-group v-model"isSendTag" :max"1"><el-checkbox v-for"(item, index) in isSendTagOptions" :key"index" :label"item.value">{{item.…

PDF转Word,1行Python代码就够了,免费用

大家好&#xff0c;这里是程序员晚枫。 今年十一假期没出去旅游&#xff0c;在家里更新一套原创课程&#xff0c;&#x1f449;给小白的《50讲Python自动化办公》。 所有功能&#xff0c;都只需要1行代码&#xff0c;非常适合非程序员入门Python使用。 目前全网播放量直逼100…

Android RecyclerView点击宫格处于选择态外框变方框线,Kotlin

Android RecyclerView点击宫格处于选择态外框变方框线&#xff0c;Kotlin <uses-permission android:name"android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name"android.permission.READ_MEDIA_IMAGES" /> implementa…