[网络]TCP/IP五层协议之应用层,传输层(1)

news2024/9/21 4:32:24

文章目录

  • 一. 应用层
  • 二. 传输层
    • 端口号
    • 传输层的协议
      • UDP
      • TCP
        • TCP报头
        • TCP协议的核心机制

一. 应用层

应用层是和应用程序直接相关, 和程序猿打交道最多的一层
应用层协议, 里面描述的内容, 就是你写的程序, 通过网络具体按照啥样的形式来传输数据
不同的应用程序, 就可以用不同的应用层协议
而实际上, 开发过程中, 很多时候, 都是需要程序猿, 自定制应用层协议的

自定义应用层协议, 本质上就是对传输的数据做出约定:

  1. 约定传输的数据要有哪些信息
  2. 传输的数据要遵守啥样的格式

例如, 现在要开发一个外卖软件

信息:
请求: 用户的id, 所在的位置
响应: 商家列表(包括商家名称, 商家照片, 商家评分, 商家的简介)

确定数据的格式:
上述的数据, 都属于"结构化数据"(通过结构体来表示的数据)
而网络中传输的都是二进制字符串, 就需要对数据进行序列化
序列化的方式:

  1. 基于xml方式
    xml是一种经典的数据组织格式
    在这里插入图片描述
    xml是用成对的标签来组织的
    xml中, 标签的名字是啥, 标签如何嵌套, 都是可以自定义的
    html可以理解成一种特殊的xml, html芮然也是标签结构, 标签有哪些, 每个标签的含义是有一套标准的规范的, 不能自定义出一些自己的标签出来(后来也可以了)
  2. 基于json(当前最流行, 最广泛使用的方式)
    在这里插入图片描述
    可读性很好, 比xml更简洁
  3. 基于yml
    在这里插入图片描述
    通过缩进来表示 包含 / 嵌套 的关系
  4. 基于protobuffer(pb)
    前面几种都是文本格式, 肉眼能看懂
    pb则是二进制格式, 肉眼看不懂
    这种方式, 针对要传输的数据进一步整理和压缩了, 虽然可读性不好, 但能够把空间最充分的利用, 最节省网络带宽, 效率也最高

应用层也有一些线程的协议, 供我们直接使用: HTTP协议

二. 传输层

端口号

端口号是一个整数, 2个字节表示的无符号整数 0->65535
小于1024的端口号, 称为:知名端口号, 这些端口号分配给了一些致命的服务器程序, 作为这些服务器的"默认端口号"
在这里插入图片描述
1. 同一个机器上, 同一时刻内, 端口号不能重复绑定
查询端口号可以使用: netstat -ano
在这里插入图片描述
黄色的部分, 就是端口号, 红色的部分是PID

可以已通过netstat -ano | findstr 9090 , 查看某个端口正在被占用的程序
在这里插入图片描述
2. 两个进程, 不能同时绑定同一个端口号, 但是不同的传输层协议可以绑定同一个端口号

如果一个服务器是TCP, 一个是UDP, 此时端口号绑定同一个是可以的
如果两个TCP / 两个UDP, 使用同一个端口, 就会出现绑定失败的情况

** 3. 一个进程, 同一时刻, 可以绑定多个端口号**

传输层的协议

学习一个网络协议, 最主要的就是学习报文格式

UDP

对于UDP来说, 应用层数据到达UDP之后, 就会给应用程序数据包前面拼装上UDP报头

UDP数据报 = UDP报头 + UDP载荷
在这里插入图片描述
1. 源端口号
里面记录了程序的源端口号, 2字节
2. 目的端口号
里面记录了数据的目的地的端口号, 2字节
3. UDP长度
描述了整个UDP数据报, 占多少个字节(B)
那么2个字节, 共有16位bit, 能够表示65535(B)这么大的数据, 即能够占用64KB
一个数据报, 最长就是64KB, 不能再长了
如果我们需要传输的数据超过64K, 就需要在应⽤层⼿动的分包, 多次发送, 并在接收端⼿动拼装

如果有面试官问, UDP数据报中, 载荷最多能承载多少数据?
回答64KB, 而不是64KB - 8
4. UDP校验和
校验和, 就是数据引入冗余信息, 通过冗余信息来验证原有的数据

数据在网络传输过程中, 时可能会出错的, 例如发生比特翻转, 本来你传输的是0, 实际到了对面变成了1
那么, 就需要能够有办法, 对传输的数据进行校验:
第一层 能够发信是否出错(代价小) ---- CRC
第二层 能发现是哪一位出错, 并且能够进行纠错(代价大) ---- 海明码

在UDP中, 校验和只能够做到第一层, 发现是否有错, UDP就是使用CRC方式完成的校验
CRC是一个简单粗暴地计算校验和的方式, 循环冗余校验
设定两个字节的变量, 把数据每个字节取出来, 往这个变量上进行累加, 如果结果溢出 超过两个字节, 溢出的部分就舍弃, 得到的结果并不重要, 主要是发送方和接收方都通过这种方式进行校验, 那么理论上结果应该是相同的, 这样就认为数据没有问题

除了CRC, 还有一个常见的方法, md5
md5是未来工作中经常用到的方法, 有很多用途

md5的特点:

  1. 定长
    无论输入的内容是多长, 得到的结果, 一定是固定长度
  2. 分散
    输入的内容, 哪怕只改变一点点, 最终结果都会差异很大
    因为分散的特性, 因此非常适合做字符串hash算法
  3. 不可逆
    通过原数据, 计算md5, 成本很低, 但是从md5还原成原数据, 成本很高, 仅仅理论上可行

总结: UDP适用于对于性能要求比较高, 但是对于可靠性要求不高的场景

TCP

TCP报头

在这里插入图片描述

  1. 源端口号(2字节)
    发送方的端口号
  2. 目的端口号(2字节)
    接收方的端口号
  3. 序号(4字节)
  4. 确认序号(4字节)
  5. 4位首部长度
    指的是报头的长度, 不是总TCP报文的长度, TCP总长度从协议的角度没限制
    首部长度可以表示的数据范围: 0-15, 但是首部长度的单位是4字节, 所以一共能够表示60个字节

如果首部长度为1111, 那么表示报头有60字节

  1. 保留(6位)
    我们知道UDP的报头长度使用2个字节, 所以报头长度太小了, 但是又不能扩展
    保留, 就是在TCP报头中, 提前申请好一块空间, 这个空间暂时不用, 但是说不定未来会用上
  2. 六位标志位(TCP的灵魂)
  3. 窗口大小(2字节)
  4. 校验和(2字节)
  5. 紧急指针(2字节)
  6. 选项
    选项是optional, 可选的, 可以选择加还是不加
    如果选择不加, 选项长度是0, 那么此时报头长度就是20字节(一行4个字节, 一共5行)
    如果选项拉满, 此时报头的长度就是60个字节

上述我们没有解释的概念, 会在后面慢慢介绍

TCP协议的核心机制

下面要介绍TCP10个比较核心的机制(并不是只有10个)
** 1. 确认应答机制**
就像发短信, 发送短信后, 对方回复, 接收到的消息, 就叫做"应答", 这样的数据, 称为"应答报文"
应答 => acknowledge => ack
在这里插入图片描述
第二个标志位就是应答报文, 如果这个bit位是1, 说明这就是一个应答报文
如果我们发送多条消息, 就可能会发生"后发先至"的情况:
例如:
在这里插入图片描述
就容易产生误会
但是, 后发先至, 是网络通信中, 客观存在的, 改变不了

解决办法就是, 对传输的数据, 进行编号 , 并且让应答报文的编号和发送的编号, 能够对应起来
TCP的序号, 是根据字节来编号的, 每个字节都有编号
假设TCP载荷中的数据长度是1000字节, 那么
第一个字节, 编号就是1, 第二个字节, 编号就是2… 每个字节的编号都是连续递增的(不一定是从0或1开始)

此时, 报头中, 写的序号的数值, 就是载荷部分第一个字节的序号, 因为编号是递增的, 通过第一个字节的序号, 就能知道后续字节的编号
确认序号的取值, 就是要应答数据最后一个字节的序号再 +1
在这里插入图片描述
可以理解成:

  1. 对于B来说, <1001的数据都已经确认收到了
  2. B再向A索要从1001开始的数据

发送方的数据报, 只有"序号字段"有效, 确认序号无效
接收方返回的sck, 标志位为1, 只有"确认序号"有效, 序号字段无效

2. 超时重传
网络环境, 本身就是不可靠的
数据传输过程中, 被丢弃了, 称为**“丢包”**
每个交换机 / 路由器的转发能力(单位时间转发多少个数据报)是存在上限的
一旦某个设备, 需要转发的数据量超出自身的极限, 此时多出来的部分就可能被直接丢弃掉
丢包是客观存在的随机事件, 是无法预测的
超时重传就是用来应对网络出现丢包情况的策略

正常情况下, TCP是通过 确认应答来知道数据是否被对端收到了
在这里插入图片描述

如果A传输的数据出现了丢包, 那么此时B不会收到A的数据, B也不会给出任何应答
那么A就可以根据"是否收到ACK" 来区分是否出现丢包
A从发送出数据之后, 到正常收到ACK, 肯定也会经历一些时间的
A发送完数据后, 就会进行一定的等待, 如果等待时间超过了某个阈值, 还没有收到ACK, 此时就可以任务出现丢包了
如果发现丢包, 就要进行重传
在这里插入图片描述
如果是ACK丢了呢?

在这里插入图片描述
此时, 站在A的角度, A无法区分是数据丢了, 还是ACK丢了, 所以A做的事情只能是重传
很明显, 此时B就会收到两份重复的数据
此时, B就会针对收到的数据进行去重

接收方, 操作系统内核中, 存在一个数据结构, “数据缓冲区”, 类似于PriorityBlockingQueue
在这里插入图片描述
B收到数据后, 层层分用, 分用到TCP这一层的时候, 会有一个阻塞队列 数据结构, 把收到的数据有序的放在这个阻塞队列中
在这里插入图片描述B收到重复的数据不要紧, 我们只需要确保应用层在读取数据的时候, 不要读到重复的数据, 应用层是从这个阻塞队列中的队首读取数据的
放的过程中, 就会根据当前数据的序号, 在队列中进行判断, 判定这个数据是否在队列中存在(或者曾经在队列中存在过), 只要存在过, 这个新的数据就不会进入队列, 而是直接丢弃
B如果收到重复的数据, 就可以推断出刚才的ack丢包了, 所以要重新发送ack
网络传输中, 可能会发生后发先至, A按照1 2 3 4的顺序write, 那么B read的时候, 也要按照1 2 3 4read, 虽然传输的过程可能出现后发先至, 是乱序的, 但是不要紧, 在接收缓冲区中, 会对收到的数据先排个序, 让序号小的在前面, 序号大的在后面, 并且数据和数据之间的序号始终都是连续的, 如果前面的数据还没到, 会给这个数据留一个位置, 等待数据过来

超时重传, 超过的时间, 不是固定的数值, 而是会动态变化的
随着重传轮次的增加, 会变得越来越长

假设第一次传输数据, 等待50ms, 就触发重传, 重传之后, 等待100ms, 如果还是收不到ack, 再等待150ms…

超时时间间隔会越来越长, 重传的频率越来越低
重传多次的原因, 大概率是网络出现了严重故障了, 接下来的重传, 能成功的可能性比较低, 如果要是重传的越来越快, 非但得不到好的结果, 而且浪费很多系统资源
如果网络确实出现严重故障了, 重传若干次, 还是不成功, 达到一定次数阈值, 就会尝试**“重置连接”**
触发一个**“重置报文”(RST)**尝试重置连接
在这里插入图片描述
第四个标志位, 即RST
重置连接就是通信双方清空之前tcp传输过程中的中间状态, 重新开始传输数据
如果网络出现严重故障, RST报文也无法顺利完成, 此时只能断开连接了(释放掉保存的对端的信息的数据结构)

TCP可靠传输, 是依靠 确认应答 和 超时重传 这两个机制保证的

下篇文章继续介绍TCP核心机制

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

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

相关文章

PHP 使用Spreadsheet写excel缓存导致内存不断增加

这里写自定义目录标题 问题描述问题解决 问题描述 新增了 Spreadsheet 用于写 excle 文件。 从网上查找一些实例后&#xff0c;封装成 createExcelFormData 函数如下&#xff1a; /*** brief 按照指定的键&#xff0c;将 array2(关联数组) 合并到 array1(关…

【C#】VS插件

翻译 目前推荐较多的 可以单词发言&#xff0c;目前还在开发阶段 TranslateIntoChinese - Visual Studio Marketplace 下载量最高的(推荐) Visual-Studio-Translator - Visual Studio Marketplace 支持翻译的版本较多&#xff0c;在 Visual Studio 代码编辑器中通过 Googl…

YOLOV8实现小目标检测

YOLOV8小目标检测 前言&#xff1a;&#xff1a; yolo版出现很多&#xff0c;基本大同小异 但是这些差异让我们考虑在实验中使用哪个版本会比较好&#xff01; 在对小目标检测的过程中&#xff0c;yolov7相比yolov8性能更加好。 如果我们还是想使用yolov8&#xff0c;也是可以实…

大模型获利「攻略」浮出水面!ToC 蓬勃发展,ToB 蕴含奥秘

前言 自去年引发“百模大战”&#xff0c;到近日开启“行业价格战”&#xff0c;中国大模型行业迈入了新的发展阶段。在近期的智源大会上&#xff0c;众多专家分享了对大模型发展现状的见解。结合 IDC 近期发布的大模型实测报告以及 Scale AI 的“AI 就绪报告”&#xff0c;大…

热榜:24年秋招没有金九银十?地信应届生想就业,如何入场?

秋招的“金九银十”即将结束&#xff0c;你的秋招到哪一步了&#xff1f; 是早已收获满满offer&#xff0c;还是仍然在海投面试中&#xff0c;亦或者根本没开始呢&#xff1f; 2024年的就业环境到底如何&#xff1f;上周&#xff0c;“2024年的就业环境到底如何&#xff1f;”…

LeetCode(04) 最接近的三数之和 【双指针】

题目描述 给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数&#xff0c;使它们的和与 target 最接近。 返回这三个数的和。 假定每组输入只存在恰好一个解。 解题思路 首先进行数组排序&#xff0c;时间复杂度 O(nlogn)&#xff1b;在…

花3000元自学AI大模型后,她薪水涨了20%

“我看到了一个充满无限可能的新世界”&#xff0c;在面试完AI产品经理这一岗位后&#xff0c;陈漫在社交平台上如此描述自己的感受。 AGI大模型浪潮席卷全球&#xff0c;技术革新越是凶猛&#xff0c;人们的失业焦虑便越加强烈。为了应对AI带来的冲击&#xff0c;有些人决定“…

c++—多态【万字文章】

目录 C—多态1.多态的概念2.多态的定义及实现2.1多态的构成条件2.2虚函数的重写2.2.1虚函数重写的两个例外&#xff1a;2.2.1.1协变2.2.1.2析构函数的重写 2.3 c11的override和final2.3.1final2.3.2override 2.4 重载、重写、重定义的对比 3.抽象类3.1抽象类的概念3.2接口继承和…

组件上的v-model(数据传递),props验证,自定义事件,计算属性

一.props验证 在封装组件时对外界传递过来的props数据进行合法性校验&#xff0c;从而防止数据不合法问题。 1.基础类型检查 String,Number,Boolean,Array,Object,Date,Function,Symbol 2.多个可能的类型 3.必须项校验 4.属性默认值 5.自定义验证函数 <template>&…

CAD2020安装方法

文章目录 下载安装包打开压缩包打开文件夹打开CAD2020文件夹双击运行Setup.exe点击安装选择我接受 点击下一步路径默认点击安装等待加载完成安装完成点击立即启动点击OK点击输入序列号点击我同意点击激活输入序列号和 产品钥密点击下一步选择我具有 Autodesk 提供的激活码以管理…

【北京迅为】《STM32MP157开发板使用手册》- 第二十八章Cortex-M4外部中断实验

iTOP-STM32MP157开发板采用ST推出的双核cortex-A7单核cortex-M4异构处理器&#xff0c;既可用Linux、又可以用于STM32单片机开发。开发板采用核心板底板结构&#xff0c;主频650M、1G内存、8G存储&#xff0c;核心板采用工业级板对板连接器&#xff0c;高可靠&#xff0c;牢固耐…

SRT3D: A Sparse Region-Based 3D Object Tracking Approach for the Real World

基于区域的方法在基于模型的单目3D跟踪无纹理物体的复杂场景中变得越来越流行。然而&#xff0c;尽管它们能够实现最先进的结果&#xff0c;大多数方法的计算开销很大&#xff0c;需要大量资源来实时运行。在下文中&#xff0c;我们基于之前的工作&#xff0c;开发了SRT3D&…

一、轻松部署的大模型开发平台dify.ai

一、轻松部署的大模型开发平台dify.ai 今天学习了大模型&#xff0c;顺便介绍的是一个名为dify.ai的神奇平台&#xff0c;它能让你轻松部署和使用大模型&#xff0c;即使你是编程小白也不用担心。 官网&#xff1a;https://dify.ai/zh 什么是大模型&#xff1f; 首先&#…

C++ nullptr 和NULL的区别

个人主页&#xff1a;Jason_from_China-CSDN博客 所属栏目&#xff1a;C系统性学习_Jason_from_China的博客-CSDN博客 概念概述&#xff1a; 在C中&#xff0c;nullptr 和 NULL 都是用来表示空指针&#xff0c;但它们之间有一些重要的区别&#xff1a; nullptr和NULL之间的区分…

ceph简介

ceph存储简要概述&#xff1a; 通过将文件分解成固定大小对象&#xff0c;然后存放于pool中&#xff0c;每个pool中 可包含多个pg&#xff0c;每个pg中又可包含多个osd 通过crush算法 最终数据落盘到osd中去。 一、ceph 删除osd 步骤1 修改osd数据操作权重值 ceph osd crush r…

【贪心算法】贪心算法

贪心算法简介 1.什么是贪心算法2.贪心算法的特点3.学习贪心的方向 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f496;&#x1f496; 你的支持是对我最大的鼓励&#xff0c;我们一起努力吧!&#x1f603;&#x1f603; 1.什么是贪心算法 与其说是…

C++ | Leetcode C++题解之第401题二进制手表

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<string> readBinaryWatch(int turnedOn) {vector<string> ans;for (int i 0; i < 1024; i) {int h i >> 6, m i & 63; // 用位运算取出高 4 位和低 6 位if (h < 12 &&a…

如何在算家云搭建MindSearch(智能搜索)

一、MindSearch简介 MindSearch是一款由上海人工智能实验室书生浦语团队提出了 MindSearch&#xff08;思索&#xff09;框架&#xff0c;旨在提供高效、精准的信息检索服务&#xff0c;能够在 3 分钟内主动从 300 网页中搜集整理有效信息&#xff0c;总结归纳&#xff0c;解决…

[“1“, “2“, “3“].map(parseInt)结果

parseInt 的用法 parseInt 是 JavaScript 中的一个全局函数&#xff0c;用于将字符串转换为整数。它的基本语法如下&#xff1a; parseInt(string, radix);string&#xff1a;要解析的字符串。radix&#xff08;可选&#xff09;&#xff1a;字符串的基数&#xff0c;可以是 …

初级练习[2]:Hive SQL查询汇总分析

目录 SQL查询汇总分析 成绩查询 查询编号为“02”的课程的总成绩 查询参加考试的学生个数 分组查询 查询各科成绩最高和最低的分 查询每门课程有多少学生参加了考试(有考试成绩) 查询男生、女生人数 分组结果的条件 查询平均成绩大于60分的学生的学号和平均成绩 查询至少…