JavaEE 网络原理——TCP的工作机制(初篇 包含 UDP 协议的再次阐述)

news2024/11/25 0:39:13

文章目录

  • 一、再次简述 UDP 协议
  • 二、再次简述 TCP 协议
  • 三、描述部分 TCP 内部的工作机制
    • 1. 确认应答
    • 2. 超时重传

前提:
在前面的文章中,我向大家分别简单介绍了 TCP 协议和 UDP 包装一个数据形成数据报发送信息。
除此之外,还通过代码编写了 UDP 和 TCP 协议下的 客户端和服务代码。
这篇文章就是对 UDP 协议和 TCP 协议进行更进一步的解释。

一、再次简述 UDP 协议

UDP 协议特点:
无连接,不可靠传输,面向数据报,全双工。
UDP 报文 = UDP 报头 + UDP 载荷
在这里插入图片描述
如上图所示,这就是一个有关 UDP 的报文传输信息的格式

有关 UDP 的报头:

  • UDP报头的创建
    UDP 会将载荷数据通过 UDP socket,也就是 send 方法拿来的数据基础上在前面拼接上几个字节的报头。
    注:这里的拼接相当于字符串拼接(是二进制的形式)

  • UDP 报头中的属性
    UDP 报头中包含了一些特定的属性,携带了一些比较重要的信息。
    不同的协议,功能不同,报头中带有的属性信息就不同。
    对于 UDP 来讲,报头一共就是有 8 个字节,分成 4 个部分(每个部分 2 个字节)

我们知道,在一次网络通信中,需要涉及到五元组,分别为:
源 IP,目的 IP,源端口,目的端口,协议类型。
我们要知道,在 UDP 报头中存储的UDP报文长度,其中指定了 UDP 整个数据报的长度就是 2 个字节对于 2 个字节所能表示的范围是,0 -> 65535,换算成单位也就是 64 kb。

也就是说,根据报头中的 UDP 报文长度 的规定,我们可以知道,对于一个 UDP 数据报,报头+载荷 的长度是不能超过 64kb 的。

一个小问题:
如果这里的应用层数据报超过了 64 kb怎么办?

  1. 需要在应用层通过代码的方式针对应用层的数据报进行手动拆包,拆成多个包通过 UDP 的数据报形式传输。(也就是说,多次 send)
  2. 不使用 UDP 改为 TCP 传输(TCP没有限制)

简单解释校验和
检验和的作用其实很明确,就是验证传输的数据是否正确。
我们都知道,网络传输,实际上就是光信号 / 电信号的传输。这些有可能会受到一些物理环境的影响,导致传输的数据发生细微的变化,从而产生错误。
例如:1111000 -> 1111001

二、再次简述 TCP 协议

TCP 全名叫做,控制传输协议。和名字所表示的含义一样,就是要对数据进行一个详细的控制。

TCP 协议段落格式和 UDP 的有很大的差别,下面,我通过一个简单的图示来解释 TCP 协议中的部分关键信息

TCP 报文 = TCP报头 + TCP 载荷

在这里插入图片描述
如上图所示,就是一个 TCP 数据报中所包含的内容,下面进行部分解释

  • 16位源端口号 / 16位目的端口号:与 UDP 一样,都是表示端口号。

  • 32 位序号 / 32 位确认号后面解释。。

  • 4 位首部长度:一个 TCP 报头,长度可变,不像 UDP 一样固定 8 个字节。
    所以,首部长度就是描述了 TCP 报头具体多长。(需要注意的是,此处的首部长度是 4bit 位)

  • 保留 6 位:顾名思义,就是先保留一个空位,防止之后有其他使用。其实,也就是为了以后便于扩展来考虑的。

  • 6 位标志符:

  • URG :紧急指针是否有效。
  • ACK : 确认号是否有效。
  • PSH : 提示接受端引用程序立即从 TCP 缓冲区将数据读走。
  • RST : 要求对方重新建立连接。(我们将携带 RST 表示的称之为 复位报文段)
  • SYN : 请求建立连接。(我们将携带 SYN 的表示称之为 同步报文段)
  • FIN : 通知对方,本段要关闭了。(我们将携带 RST 标识的称之为 报复性文段)

详细的功能,本人会在后面的文章中进行简单分析。

  • 16 位窗口大小后面解释。。
  • 16 位校验和:与 UDP 中的校验和同理。
  • 选项:在这里相当于对这个 TCP 报文的一些属性进行解释说明,可以先忽略。

不难发现,上面的内容我们能理解的东西非常有限,所以,要更好的理解 TCP 数据报,就需要进一步了解 TCP 后续的工作机制。

三、描述部分 TCP 内部的工作机制

TCP 是一个很复杂的协议,其中有许多的机制。当前我们主要讨论比较重要的 10 个核心机制

1. 确认应答

这里的确认应答,是实现可靠传输的最核心机制。
这里的 “可靠” 并不是说一定 100% 将信息发送给对方,而是说尽力而为,如果实在传输不过去,至少还可以知道

这里为了方便解释,在这里本人就引入一个简单的例子。如下:
这个例子里有两个人,我(本人),外卖店老板。

在这里插入图片描述
如上图所示,当我收到 “好的,没问题” 此时,我就会知道,本人发的消息此时已将顺利的被外卖店老板收到了。(也就是说此时的信息没有丢包)
所以说,这里的 “好的,没问题” 就被称为应答报文

但是,在这里,如果我隔了好大一会店家还没有给我回消息,这就说明发的消息大概率是凉了。。
在生活中,上面的情形和打电话非常类似。

这里考虑更复杂的一些情况
如图:

在这里插入图片描述
需要注意的是,这里是我 连续发送两个消息
要注意的是,在网络上存在一种情况叫 “后发先至”。在这个情况下,收到消息的顺序可能会发生变化。也就是说会成下面这样,如图:
在这里插入图片描述

此时,由于 “后发先至” 的问题,我先收到的信息是 “滚,不行”,后收到的是 “好的,没问题”。

简单解释 “后发先至”
所谓后发先至,可以简单理解为结婚时的车队。在两家较长的路上,车队之间必然会出现后面的个别车辆跑过头车走到前面去。
在网络中也是如此,两个主机之间存在多条路线,数据报1 和 数据报2 所走的路线可能不同,在不同的路由器 / 交换机上的转发速率也不相同。所以,这两个数据报到达的顺序,就更存在变数了。

当然上面的 “后发先至” 问题也是有解决办法的。就是将 传输的数据 和 应答报文 都进行编号,就可以了。
如图:
在这里插入图片描述
如图,在这里引入序号之后,此时就不怕顺序错乱了。

解释序列号在 TCP 协议中的位置

在这里插入图片描述

32 位序号, 在这里就是来标记数据的 (包括应答报文)
32 位确认序号, 这里的确认序号,只有 应答报文有。(普通报文中确认序号字段里的值毫无意义)
对于,如何确定这个报文是应答报文,这里取决于上图中划红线的 ACK 标志符。
此处 ACK 这个标志位如果是 1 ,就表示是 应答报文。 如果是 0,就表示不是应答报文

简单说明 TCP 序号的编号方式
我们知道,TCP 是面向字节流的。所以 TCP 的序号也是按照字节的方式来进行编号的!
例如,这里有一段数据 是 1000 个字节
呢么,假设此时是从 1 开始编号,此时的第一个字节序号就是 1 。第二个字节序号就是 2 。。。以此类推。
但是需要注意的是,这 1000 个字节都是属于一个 TCP 报文。报头中记录的只是当前第一个字节的序号。所以,此处的报头的序号就是 1。
如果接下来再发第二条数据,此时 TCP 数据报的第一个字节序号就是 1001 。如果长度是 1000,呢么到最后时的字节序号就是 2000.
所以,此时这里的 TCP 报头就是 1001.

所以,综上所述,TCP 知道了头一个字节的序号在根据 TCP 报文长度就很容易知道每个字节的序号。

简单总结:
TCP 的可靠传输能力,最主要就是通过确认应答机制来保证的。所以,通过应答报文,就可以让发送方清楚地知道传输是否成功。进一步引入的序号和确认序号,可以对多组数据进行详细的区分。

2. 超时重传

在前面的确认应答的讨论中,我们所讨论的,只是 顺利传输 这样的情况。呢么,如果出现丢包的情况呢?

所谓的丢包,基本涉及到两种情况
1.发送的数据丢失
2.返回的 ack 丢失

对于上面的两种情况,在发送方看来就是没有收到 ack 并不能做出任何区分。 也就是说会一视同仁,都认为是丢包。

所谓 “丢包” 其实是一个概率性事件。在通常情况下丢包的概率是比较小的。因此,如果重新发送一下这个数据报,还是有很大概率传输成功。

所以,根据上述的情况。TCP 就引入了重传机制。 也就是在丢包的时候再发送一次相同的数据。

但是,在重传前,我们要考虑一个问题:
当前的这次传输,到底是丢包,还是 ack 传输较慢在路上。

同样,根据上述的情况,TCP 直接引入了一个时间阈值。也就是说,当发送方发出一个数据后,就会等待 ACK ,此时开始计时。如果在时间阈值内没有收到 ACK ,无论此时是否在路上,还是丢了,都视为丢包了!

视为丢包的情况有下面两种,如图:
在这里插入图片描述
注意上面的第二张图,对于主机 B 而言,1~1000 就接受了两次。这其实是一个很严重的问题,如果说此时发送的是一个 支付请求 呢?
在 TCP 中其实也考虑到了这一点,有着一个特殊处理——去重

在 TCP 中,存在着一个 “接收缓冲区” 这样的存储空间。(也就是操作方操作系统内核中的一段内存)
每个 TCP 的 socket 对象都有一个接收缓冲区。
在上面的图中,主机 B 接收到 主机 A 发来的数据。其实是 B 的网卡获取到数据,然后将个数据存放到 B 对应的 socket 的接收缓冲区中。(这里其实可以想象成存入到了一个阻塞队列中)
根据数据的序号,TCP 很容易识别当前的接收缓冲区中的两个数据是否重复。
如果重复,则就会将后面的这份数据丢弃。保证程序调用的 read 读取到的数据一定不重复!

对于上面提到的 “接收缓冲区” 严格的来讲,这里可以理解成一个 优先级队列 或者 有序队列。
因为在前面我们提到过,网络传输的数据可能会后发先至。这里使用这个队列就是对收到的数据进行排序,确保 read 读取到的数据是有序的。

到这里,我们描述了 确认应答 传输顺利的情况。超时重传 传输故障的情况。两者之间的配合,共同支撑起 TCP 的可靠性!

码子不易,您小小的点赞是对我最大的鼓励!!!

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

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

相关文章

QT中摄像头的使用

QT中摄像头相关类 摄像头的使用 QT中摄像头的使用主要分为三个方面,显示画面、抓取图片和视频录制。这三个方面对应着摄像模块的三种模式。模式如下: ConstantValueDescriptionQCamera::CaptureViewfinder0相机仅配置为显示取景器。QCamera::CaptureSt…

React入门

一、react开始 1、react是什么 用于构建用户界面的JavaScript库 操作DOM呈现页面 (发送请求获取数据和处理数据不由react处理)fessbook开发 2、为什么要学 原生js操作DOM繁琐、效率低 使用原生js直接操作DOM,浏览器会进行大量重绘重排 原…

计算机视觉面试题整理

1、介绍目标检测网络yolo系列以及ssd系列的原理,yolo对小目标检测不好的原因,除了缩小anchor外还可以如何改善? Yolo目标检测:YOLO是一种实时目标检测算法,其核心思想是将目标检测问题归为一个回归问题,直…

Android毕业设计,基于Android 语音朗读书籍管理系统

视频演示: 基于Android 语音朗读书籍管理系统 基于 Android 的语音朗读书籍管理系统可以提供用户管理书籍、朗读书籍的功能。以下是一个简单的步骤和功能列表: 用户注册和登录功能: 用户可以注册新账号或使用现有账号登录系统。用户信息可以包…

【rust/egui】(十一)使用rfd选择文件并使用serde_json进行序列化

说在前面 rust新手,egui没啥找到啥教程,这里自己记录下学习过程环境:windows11 22H2rust版本:rustc 1.71.1egui版本:0.22.0eframe版本:0.22.0上一篇:这里 rfd-Rusty File Dialogs 一个跨平台的…

只需3步部署Django项目到Kubernetes上

1. 目标 本文讲述了如何通过3步,把Django项目部署在K8S上。 本文适用读者: 了解Django项目的开发。了解K8S的用途。 2. 具体步骤 把一个Django项目部署在Kubernete环境上,只需以下3步: 创建镜像部署在Kubernetes环境上配置MyS…

linux命令查看谁在使用服务器的GPU

命令:查看GPU使用情况 nvidia-smi 可以知悉GPU占用情况和主要使用GPU的进程,如下图所示: 实时查看gpu使用: nvidia-smi -l 1 表示每隔1s刷新一下,数字可更改。 查看进程的归属者 方法一:ps -f -p pid…

360极速浏览器X终极奥义之——更改划词工具条的搜索为百度搜索 2023更新版

原文为2019版本,具体已失效,2023更新。 1.需要将 https://www.so.com/s?q%s&src360csex_zoned字符串对应的十六进制码替换为 https://www.baidu.com/s?wd%s&src360csex_z对应的十六进制码。 2.需要删除后面的"oned"以保证转换出来…

冒泡排序~

1、对应长度len 数组,需要进行 len -1 趟冒泡,每趟冒泡,将最大(小)元素排列到最后无序位置 2、每趟冒泡从第一个元素开始,邻近两两比较,找出最大元素 每一趟冒泡,都进行元素交换&am…

基于频谱信息的图像去噪与恢复——使用约束最小二乘方滤波法

大家好,我是带我去滑雪! 随着科学技术的不断发展,信息的交流和获取已不再受到时空的限制,已经成为人们日常生活中不可或缺的一部分。图像作为人类信息交流中的重要载体,起着不可替代的作用。频谱图像去噪复原方法是一种…

Hive【Hive(一)DDL】

前置准备 需要启动 Hadoop 集群,因为我们 Hive 是在 Hadoop 集群之上运行的。 从DataGrip 或者其他外部终端连接 Hive 需要先打开 Hive 的 metastore 进程和 hiveserver2 进程。 Hive DDL 数据定义语言 1、数据库(database) 创建数据库 c…

YOLOv8『小目标』检测指南

前言 目前博主课题组在进行物体部件的异常检测项目,项目中需要先使用 YOLOv8 进行目标检测,然后进行图像切割,最后采用 WinCLIP 模型 进行部件异常检测 但是在实际操作过程中出现问题, YOLOv8 模型目标检测在大目标精确度不错&a…

Vue的详细教程--入门

🥳🥳Welcome Huihuis Code World ! !🥳🥳 接下来看看由辉辉所写的关于Vue的相关操作吧 目录 🥳🥳Welcome Huihuis Code World ! !🥳🥳 一.Vue是什么 二. Vue的特点及优势 三.使用…

IT运维:利用数据分析平台采集Windows event log数据

概述 本文将介绍如何借助Winlogbeat和Vector在鸿鹄里采集Windows event log数据,使技术人员能够在鸿鹄里更便捷和高效地分析Windows event log数据。 操作步骤 Winlogbeat是一个开源的日志数据采集器,专门用于采集Windows操作系统中的event log数据。它可…

【JAVA数据结构】包装类与认识泛型

作者主页:paper jie 的博客 本文作者:大家好,我是paper jie,感谢你阅读本文,欢迎一建三连哦。 本文录入于《JAVA数据结构》专栏,本专栏是针对于大学生,编程小白精心打造的。笔者用重金(时间和精…

解决 Cannot read property ‘key‘ of undefined

目录 问题解决1解决2最终 问题 现场环境分页查询某些条件项查询时,分页接口获取成功但是数据不渲染,页面像是卡住了: 报错 Cannot read property key of undefined 解决1 有人说 使用的el-pagination在格式化代码的时候layout属性的参数会多加…

vue基础知识十一:Vue组件之间的通信方式都有哪些?

一、组件间通信的概念 开始之前,我们把组件间通信这个词进行拆分 组件通信 都知道组件是vue最强大的功能之一,vue中每一个.vue我们都可以视之为一个组件通信指的是发送者通过某种媒体以某种格式来传递信息到收信者以达到某个目的。广义上,…

Gin 框架 解决 跨域问题

Gin 框架解决跨域问题 一点废话 在学习 Axios 的时候发现 up 使用了一个网址来提供 json 数据。因为不想加什么公众号搞啥百度网盘的,然后又刚好会一点点 go,就想着自己用 gin 框架返回一个 json 到前端页面然后从这个页面获取 json 。 这是我的go代码…

堡垒机的相关介绍

描述 堡垒机,即在一个特定的网络环境下,为了保障网络和数据不受来自外部和内部用户的入侵和破坏,而运用各种技术手段监控和记录运维人员对网络内的服务器、网络设备、安全设备、数据库等设备的操作行为,以便集中报警、及时处理及审…

javafx学习记录

1.布局 2.选择重写或实现方法(select methods to override/implements) ctrl o 3.javafx有init方法,start方法,stop方法 4.定义一个按钮,使用系统默认浏览器访问网站 5.使窗口的关闭栏,缩小扩屏栏,代码是倒数第二行 6.设置模态窗口,默认关闭模态的 下…