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

news2024/11/18 9:31:00

广播(使用 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.coloradmin.cn/o/1242030.html

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

相关文章

安卓毕业设计基于安卓android微信小程序的培训机构系统

项目介绍 本文以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c;它主要是采用java语言技术和mysql数据库来完成对系统的设计。整个开发过程首先对培训机构管理系统进行需求分析&#xff0c;得出培训机构管理系统主要功能。接着对培训机构管理系统 进行…

C#,简单修改Visual Studio 2022设置以支持C#最新版本的编译器,尊享编程之趣

1 PLS README & CHAPTER 5 用一个超简单的例子说明各版本 C# 的差异。 使用新版本&#xff08;比如C#.11&#xff09;&#xff0c;当然有一定的好处。我们在写程序的时候一般这样&#xff1a; Visual Studio 2022 默认只能这样写&#xff1a; string imageFile Path.C…

STL的认知

STL vector 头文件<vector> 初始化,定义,定义长度&#xff0c;定义长度并且赋值&#xff0c;从数组中获取数据返回元素个数size()判断是否为空empty()返回第一个元素front()返回最后一个数back()删除最后一个数pop_back()插入push_back(x)清空clear()begin()end()使用s…

最近整理一份steam搬砖的项目操作细节和详细要求

csgo饰品搬砖Steam饰品搬砖全套操作流程之如何卖货 一、国外Steam游戏装备汇率差项目 这个项目的基本原理是 购买国外Steam游戏平台上的装备&#xff0c;再在国内网易Buff平台上或国际站csgo饰品平台进行售卖。从充值汇率和两个平台的装备价格差中获得利润。 二、需要准备的硬…

企业微信身份验证

本篇主要是在上一篇获取第三方凭证基础上&#xff0c;用户通过三方网站自定义授权登录后获取用户信息&#xff0c;以实现用户绑定登录功能。 构造第三方应用授权链接 如果第三方应用需要在打开的网页里面携带用户的身份信息&#xff0c; 第一步需要构造如下的链接来获取授权c…

【Python爬虫】8大模块md文档从0到scrapy高手,第8篇:反爬与反反爬和验证码处理

本文主要学习一下关于爬虫的相关前置知识和一些理论性的知识&#xff0c;通过本文我们能够知道什么是爬虫&#xff0c;都有那些分类&#xff0c;爬虫能干什么等&#xff0c;同时还会站在爬虫的角度复习一下http协议。 Python爬虫和Scrapy全套笔记直接地址&#xff1a; 请移步这…

如何使用Google My Business来提升您的内容和SEO?

如果您的企业有实体店&#xff0c;那么使用Google My Business&#xff08;GMB&#xff09;来改善您的本地SEO并增强您的在线形象至关重要。Google My Business &#xff08;GMB&#xff09; 是 Google 提供的补充工具&#xff0c;使企业能够控制其在 Google 搜索和地图上的数字…

大白话DDD(DDD黑话终结者)

大白话DDD&#xff08;DDD黑话终结者&#xff09; 一、吐槽的话 相信听过DDD的人有很大一部分都不知道这玩意具体是干嘛的&#xff0c;甚至觉得它有那么一些虚无缥缈。原因之一是但凡讲DDD的&#xff0c;都是一堆特别高大上的概念&#xff0c;然后冠之以一堆让人看不懂的解释…

echarts产品日常奇怪需求

设置最小刻度导致好多小数&#xff0c;限制两位 yAxis 指定的y轴设置 axisLabel&#xff0c;可以格式化显示 文档地址&#xff1a;https://echarts.apache.org/zh/option.html#yAxis.axisLabel.formatter yAxis: [{type: value,name: 利率,position: right,alignTicks: true,mi…

Go lumberjack 日志轮换和管理

在开发应用程序时&#xff0c;记录日志是一项关键的任务&#xff0c;以便在应用程序运行时追踪问题、监视性能和保留审计记录。Go 语言提供了灵活且强大的日志记录功能&#xff0c;可以通过多种方式配置和使用。其中一个常用的日志记录库是 github.com/natefinch/lumberjack&am…

安装MySQL搭建论坛

课前默写&#xff1a; 1、nginx配置文件的区域有哪些 ①全局区域 ②events区域 ③http区域 2、区域模块的作用 全局区域模块主要是用户和工作进程 events区域模块配置最大连接数时需先配置:vim /etc/limits.conf 因为系统默认最大是1024 http区域模块&#xff1a;代理地…

使用宝塔安装Alist

废话不多说&#xff0c;直接上教程&#xff0c;根据我的步骤一步一步来&#xff0c;肯定可以成功&#xff01; 我这边使用一键安装的时候&#xff0c;一致报错&#xff0c;提示证书过期&#xff0c;无奈我就开始了手动安装&#xff0c;下面的教程也是手动安装的教程 首先&…

监控员工上网有什么软件

监控员工上网的软件主要用于监控员工在工作时间内的网络行为&#xff0c;包括浏览网页、使用社交媒体、发送邮件等。通过监控员工上网行为&#xff0c;企业管理者可以更好地了解员工的工作状态和行为&#xff0c;规范员工的上网行为&#xff0c;提高工作效率&#xff0c;同时也…

每日一题:LeetCode-589.N叉树的前序遍历序列构造二叉树

每日一题系列&#xff08;day 01&#xff09; 前言&#xff1a; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f50e…

【OpenCV+OCR】计算机视觉:识别图像验证码中指定颜色文字

文章目录 1. 写在前面2. 读取验证码图像3. 生成颜色掩码4. 生成黑白结果图5. OCR文字识别6. 测试结果 【作者主页】&#xff1a;吴秋霖 【作者介绍】&#xff1a;Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作&#xff01; 【…

【Unity实战】按物品掉落率,随机掉落战利品物品系统(附项目源码)

文章目录 前言开始参考源码完结 前言 当开发游戏时&#xff0c;一个常见的需求是实现一个物品随机掉落系统。这个系统可以让玩家在击败敌人或完成任务后获得随机的物品奖励&#xff0c;增加游戏的可玩性和乐趣。 在Unity中&#xff0c;我们可以通过编写代码来实现这样的战利品…

大模型AI Agent 前沿调研

前言 大模型技术百花齐放&#xff0c;越来越多&#xff0c;同时大模型的落地也在紧锣密鼓的进行着&#xff0c;其中Agent智能体这个概念可谓是火的一滩糊涂。 今天就分享一些Agent相关的前沿研究&#xff08;仅限基于大模型的AI Agent研究&#xff09;&#xff0c;包括一些论…

Ubuntu 1.84.2Visual Studio Code 下载配置与vscode查看内存Hex Editor插件,简单易懂

目录 前言 一 首先我为啥要重装Vs Code呢&#xff1f; 二 下载1.84.2Visual Studio Code 三 配置Vscode终端字体 四 安装插件 前言 这是一篇将老版本的VsCode下载至最新版的博文&#xff0c;从下载到调试全篇 一 首先我为啥要重装Vs Code呢&#xff1f; 因为我想安装这个…

14.(vue3.x+vite)组件间通信方式之pinia

前端技术社区总目录(订阅之前请先查看该博客) 示例效果 Pinia简介 Pinia 是 Vue 的存储库,它允许您跨组件/页面共享状态。 Pinia与Vuex比较 (1)Vue2和Vue3都支持,这让我们同时使用Vue2和Vue3的小伙伴都能很快上手。 (2)pinia中只有state、getter、action,抛弃了Vu…

2023年全国大学生数学建模竞赛总结

2023年全国大学生数学建模竞赛总结 一.参赛经历二.组队建议赛前准备建模手所需要具备的知识 编程手需要具备的能力 论文手论文手需要学习的知识 比赛过程 全国大学生数学建模竞赛的比赛落下了帷幕,很荣幸我能够获得国家二等奖,这对于我们队伍来说是十分荣幸的,接下来让我进行我…