【Javaee】网络原理—TCP协议的核心机制

前言

TCP/IP五层协议是互联网中的主流模型,为网络通信提供了一个稳固的框架。

主要包含了应用层,传输层,网络层,数据链路层,物理层。

本篇主要介绍传输层的TCP协议的核心机制


一.  确认应答(ack)

TCP最核心的机制为可靠传输,但可靠传输并不是保证100%的成功,而是尽可能的使数据能到达对方,可靠性的保证有两个重要机制

1.能感知到对方是否接收到数据

2.如果发现对方没有收到,就要进行重发

其中,通过确认应答机制来感知对方是否收到。

所谓的“感知对方是否收到”,是靠对方的通知。

应答报文(acknowledge),缩写为ack

网络传输中存在着后发先至的情况,当发送多个消息时,上诉机制可能可能产生问题,例如

甲向乙提出两问题,乙回答时可能发送后发先至的情况,变成了乙不同意一起吃饭,却同意做女朋友,此时,就产生了歧义。

此时,可以给传输的数据添加编号,通过编号,可以区分出数据的先后顺序。

 TCP是面向字节流的,实际上的编号是按照字节来编号的。

按照字节编号这样的机制,就是TCP的序号

在应答报文中,针对之前收到的数据进行对应编号,称为TCP的确认序号

其中,确认序号是接收方收到的数据最后一个字节序号的下一个序号(如上图,数据最后一个字节序号是1000,ack则返回1000+1,也就是1001作为确认序号)

确认序号前的数据,全部都已经被接收方接收

如果数据在发送过程中发生后发先至,后面的数据比前面的数据先一步到达,此时接收方read就会进入阻塞等待,直到读取到开头发送的数据,确报发送方write的顺序和接收方read的顺序相同时,才会解除阻塞。


二.超时重传

网络传输中并不是一帆风顺,常常会发生丢包情况

产生丢包的原因有多种

1.数据传输过程中,发生了bit翻转,收到这个数据的接收方计算校验和对不上,此时会直接丢弃该数据包。

2.数据传输到某一节点,节点负载太高了(网络高峰期),后续传输过来的数据可能直接被节点丢弃掉

TCP需要通过应答报文来区分数据是否丢包,收到应答报文(ack),就说明数据没有丢包,没收到应答报文,就说明数据丢包了。

丢包是难以预测的,TCP再强大也难以完全避免丢包,能做的只有在感应到数据丢包时重新发一次

但数据在网络传输是需要消耗时间的,“没收到应答报文”可能只是暂时没收到,等一会可能就收到了,也有可能是确实丢失,永远收不到了。

超时重传机制通过设定一个“时间限制”,如果在这个时间限制内,没有收到ack,则视为数据丢包,随后重传文件

如果数据成功发送,但ack丢包,由于发送方无法识别对方有没有收到数据,到达限制时间后也会进行重新发送,此时接收方又收到了一份相同的数据,TCP会进行去重,确保不会read到同样的数据。

超时重传的时间不是固定不变的,而是动态变化的。

发送方第一次重传,超时时间是t1,如果仍然没有ack,则会进行第二次重传,超时时间为t2

通常情况下t2>t1,每重传一次,超时时间的间隔就会变大,反复重传多次后,都没有顺利到达,TCP不会尝试重传,会先进行复位连接,发送一个一个特殊的数据包(复位报文),如果网络这会恢复了,复位报文会重置连接,使通信可以继续运行,如果网络存在严重问题,复位报文也没得到回应,此时TCP就会单方面放弃连接,连接也就无了。

确认应答和超时重传相互补充,共同构建了TCP的可靠传输机制


三.连接管理★★★(重点)

1.建立连接(三次握手)

三次握手是客户端与服务器建立连接的过程,前面提到过,连接的实质是双方保存着对方的信息

如上图所示,A请求保存B的信息,B接收到后返回ACK,然好B请求保存A的信息,A收到后返回ACK,其中,syn和ack可以同时发送,于是将这两步合并成一步,这就是三次握手。


三次握手要解决说什么问题?意义所在?

1.投石问路,初步验证通信链路是否畅通(可靠传输的前提条件)

2.确认通信双方各自的发送能力与接收能力是否都正常

3.让通信双方在通信前,对通信过程中需要用到的一些关键参数进行协商(TCP通信时的起始数据序号,就是通过三次握手协商确定的)

上诉约定的意义,在于避免“前朝的剑斩今朝的官”

假如A和B在传输数据时,数据包传输的慢,突然A和B断开了连接,过了一会A和B又重新建立了连接,虽然还是A和B两个主机连接,但可能是不同的应用程序,此时上一个没到达的数据包可能这时才到达,A和B已经是新的连接了。

针对这样“迟到”的数据包,应当直接丢弃掉。

那么,如何区分数据包是否是前朝的?

可以给每个连接都协商不同的起始序号,如果发现收到的数据和起始序号以及和最近收到的序号差距很大,则为“迟到”的数据包


2.断开连接(四次挥手)

断开连接就是通信双方各种把对端的信息删除掉(优雅的)

前面介绍“超时重传”时提到单方面释放连接,则是没那么优雅的进行断开连接(会造成资源浪费)

通信双方各种给对方发送“FIN”,各自给对方返回“ACK”

三次握手的三次,是因为中间的syn与ack进行了合并

对于四次挥手来说,中间ACK和FIN不一定能够合并。

原因是四次挥手ACK是内核控制的,但FIN的触发则是通过应用程序调用close

这中间存在着时间间隔

3.TCP的状态

1)LISTEN状态

服务器进入的状态,表示已经绑定好端口,服务器初始化完毕,准备连接客户端

2)ESTABLISHED

客户端和服务器都保存好了对方的信息,可以传输后续数据业务(三次握手后)

3)CLOSE_WAIT

被动断开连接的一方进入的状态,等待代码执行close方法

如果发现服务器端存在大量CLOSE_WAIT状态的TCP连接,说明服务器代码可能存在问题,应检查代码是否有close操作

4)TIME_WAIT

主动断开连接的一方进入的状态,此处的TIME_WAIT按照时间等待,达到一定时间后连接也就释放了。

为何不直接释放连接?而是要等待一段时间??

TCP在传输的过程中,任何一个数据都有可能丢包

此处的等待,就是以防最后一个ACK丢包,如果最后一个ACK丢包,则会重传FIN

 能够重发一次ACK的前提是A这边的连接不能释放(如果释放就无法返回数据)

保留一段时间没有收到重传的FIN,则说明刚才的ACK应该是收到了,就可以释放连接

TIME_WAIT持续时间通常为2MSL

四.滑动窗口

1.概述

提起滑动窗口,学过算法的同学应该知道,算法思想中也有滑动窗口,其实,算法中的“滑动窗口”正是借鉴自TCP的滑动窗口

为什么TCP要滑动窗口???
TCP希望能在可靠传输的基础上,也能有不错的效率,为此引入滑动窗口。

此处的提高效率,只是“亡羊补牢”,使传输的效率损失尽可能降低(效率低于UDP)

按照以上方式(无滑动窗口),A每次发送一个数据给B,都得等待B的ack才能发下一个,这种方式的低效的。

改进方案则是把“发一个等一个”改成“发送一批等待一批”,把多次等待ack的时间合并成一次,这样等待的时间少了,效率也就提高了。

批量发送的数据越多,效率越高,此时把批量发送数据且不需要等待的数据的量称为窗口大小

以下图为例,主机A批量发送数据包后,当收到第一个ack后,就会立即发送下一条数据,窗口向右移动

2.丢包问题

情况一

数据包抵达,ACK丢包(如图)

此时不需要做任何处理,批量发数据,ACK丢失也只是丢失其中的一部分,不可能全丢了

通过确认序号,可以判定前面的数据都收到了,接下来要发送的数据就从确认序号这里往后发

情况二

发送方数据丢包

如图,确认序号会在收到后面的数据包时反复返回丢失段数据包的序号,提醒发送方进行重发,发送方识别出哪个数据包丢失后,针对这个数据包进行重传,其他顺利到达的数据包无需重传,这就是“快速重传”

快速重传可以视为滑动窗口下搭配的超时重传。


五.流量控制

滑动窗口窗口的大小对于传输数据的性能是直接相关的

窗口的大小不能无限的大,通信是双方的事情,发送方发送的快了,也得确保接收方能够处理的来。

发送方与接收方之间,有着一个接收缓冲区,用于存放发送方发送的数据(本质为阻塞队列)

如果发送速度特别快,接收方处理接收速度比较慢,就会使接收缓冲区充满,此时发送方强行发送数据则会丢包,这就需要让接收方的处理能力反向制约发送方的发送速度。

可以通过“定量”的方式,来实现制约

如果空闲空间越大,则可以认为应用程序处理速度比较快,就可以让发送方发送的快一些,设置一个更大的窗口大小。

如果空闲空间小,则可以认为应用程序处理速度比较慢,就可以让发送方发送的慢一些,设置一个更小的窗口大小shu

TCP接收方接收到数据的时候,就会把接收缓冲区剩余空间大小通过ACK数据包反馈给对方,例如

 流量控制,并不是TCP独有的机制,其他的协议可能也会涉及流量控制


六.拥塞控制

拥塞控制与流量控制是有关联的,也是“踩刹车”

虽然TCP有了滑动窗⼝这个⼤杀器,能够⾼效可靠的发送⼤量的数据.但是如果在刚开始阶段就发送⼤量的数据,仍然可能引发问题。

因为⽹络上有很多的计算机,可能当前的⽹络状态就已经⽐较拥堵.在不清楚当前⽹络状态下,贸然发送⼤量的数据,是很有可能引起雪上加霜的。

如下图,有一个节点本身负载已经很高,如果A依旧快速发送数据包,这个节点可能就直接丢包了

但由于中间节点数量多,每次传输数据走的路径还不一样,哪一个节点负载高难以精确的发现

那么要怎么衡量节点的负载来控制发送速度?

拥塞控制中,把中间传输的节点,视为一个整体,不关注具体的实现细节。

通过做实验的方式,找到一个合适的发送速度(面多加水,水多加面)

例如:1.先按照一个比较小的速度发送数据,数据非常畅通,没有丢包,说明网络传输数据整体比较畅通,就可以加快发送速度

2.增大到一定的速度后,发现丢包了,说明网络上可能存在拥塞,就减慢发送速度

3.减速到一定速度后,发现不丢包了,则又开始增加数据发送速度

........

如此反复

拥塞控制的窗口是动态变化的,需根据实际情况来调整

拥塞控制和流量控制都是踩刹车,这两个机制会同时起作用,最终实际发送发送窗口的大小,取决于上述两个机制得到的方式窗口的较小值。

流量控制与拥塞控制都是对TCP可靠传输的补充
 


七.延时应答

延时应答的目的是为了提高效率,尽可能降低可靠传输带来的性能影响。

发送方发送数据时,接收接收后不着急马上返回ack,而是数据发送一定数量(或可以按照一定时间)后,再返回ack。


八.捎带应答

捎带应答是再延时应答的基础上,提高效率的机制

把返回的业务数据和ack合二为一(减少包的数量,提高效率)。

正常情况下,发送方和接收方数据发送为“一问一答”,ack和发送数据业务之间存在着时间间隔,无法合并。

但是ack有着延时应答,可以将ack发送的时间往后拖,这一拖,可能赶上发送数据业务的时间,于是发送数据业务时,可以把ack也一起带上。

四次挥手中,FIN和ACK无法合并也是因为两个数据包之间存在着时间间隔。

但如果此时触发延时应答,ACK等待FIN发送时捎带发送,那么四次挥手也能够变成三次挥手


九.面向字节流

TCP协议传输时是通过字节流传输的,前文已经介绍过,这里主要介绍面向字节流所产生的粘包问题。

什么是粘包问题??

以图为例,当A向主机发送数据时,数据到达接收缓冲区

当应用程序读取接收缓冲区时,有各种读法(如aa,abb,bccc等),但“aaa”,“bbb”,“ccc”才是正确的读法,如不为这样的读法,应用程序读取的数据包与原数据包有所偏差,会产生不同的结果。

粘包问题就是应用层数据包在TCP缓冲区中连城一片,粘在一起。

应如何解决粘包问题?

方案一:

关键在于明确每个数据包的边界,可通过分隔符来区分包和包的边界。 

方案二:
约定每个应用层数据包的长度,利用数据包开头的两个/四个字节来定义长度


十.异常处理

在遇到一些异常情况时,TCP协议有着解决问题的方案

1)进程崩溃

在Java中表现为抛出异常,但没人catch,最终异常到了JVM里,进程直接崩溃

在这过程中,操作系统会进行善后,会关闭文件描述表里对应的文件,socket文件也会触发正常的关闭流程(四次挥手)

2)主机关机(正常流程)

操作系统会关闭掉所有的进程,关闭的过程中同样会进行四次挥手。

此时有两种情况

a)当四次挥手快时,四次挥手结束后主机关机

b)当四次挥手慢时,可能每来得及挥完就关机了(如图)

此时,B应没收到ACK,就会触发超时重传,可能会重传很多次,但达到上限后只能单方面主动放弃连接

3)主机掉电(拔电源)

分为两种情况

a)发送方掉电

此时B会发送探测报文,若A有ACK,说明A没有掉。

如果多次发送探测报文,没有回复,则认为A掉了

探测报文是周期性发送的,同时这个报文也是探测对方“生死”的,也被称为“心跳包”

b)接收方掉电

此时,B就不会发送ACK给A了,A会触发超时重传,重传的数据也没有响应,多次后会重置连接,重置连接没有响应后,A会单方面断开连接

4)网线断开

和主机掉电非常相似

站在A的视角,ACK收不到,超时重传,重置连接,最后单方面放弃连接

站在B的视角,探测报文没有回复,最后单方面放弃连接


TCP不只有10个机制,本篇只是提到较为核心的机制

以上便是全部内容,如有不对,欢迎指正

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

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

相关文章

SQL 干货 | SQL 半连接

大多数数据库开发人员和管理员都熟悉标准的内、外、左和右连接类型。虽然可以使用 ANSI SQL 编写这些连接类型,但还有一些连接类型是基于关系代数运算符的,在 SQL 中没有语法表示。今天我们将学习一种这样的连接类型:半连接(Semi …

内网穿透:如何借助Cloudflare连接没有公网的电脑的远程桌面(RDP)

内网穿透:如何借助Cloudflare连接没有公网的电脑的远程桌面(RDP)-含详细原理配置说明介绍 前言 远程桌面协议(RDP, Remote Desktop Protocol)可用于远程桌面连接,Windows系统(家庭版除外)也是支持这种协议的,无需安装…

[RK3566-Android11] 使用SPI方式点LED灯带-JE2815/WS2812,实现呼吸/渐变/随音量变化等效果

问题描述 之前写了一篇使用GPIO方式点亮LED灯带的文章 https://blog.csdn.net/jay547063443/article/details/134688745?fromshareblogdetail&sharetypeblogdetail&sharerId134688745&sharereferPC&sharesourcejay547063443&sharefromfrom_link 使用GPIO…

C++20中头文件ranges的使用

<ranges>是C20中新增加的头文件&#xff0c;提供了一组与范围(ranges)相关的功能&#xff0c;此头文件是ranges库的一部分。包括&#xff1a; 1.concepts: (1).std::ranges::range:指定类型为range&#xff0c;即它提供开始迭代器和结束标记(it provides a begin iterato…

博弈论 C++

前置知识 若一个游戏满足&#xff1a; 由两名玩家交替行动在游戏进行的任意时刻&#xff0c;可以执行的合法行动与轮到哪位玩家无关不能行动的玩家判负 则称该游戏为一个公平组合游戏。 尼姆游戏&#xff08;NIM&#xff09;属于公平组合游戏&#xff0c;但常见的棋类游戏&…

idea(2017版)创建项目的搭建方式

目录 一、普通Java项目 二、普通JavaWeb项目 三、maven的Java项目 四、maven的JavaWeb项目 一、普通Java项目 1.创建新项目 2.因为是普通的java项目&#xff0c;所以先点最上面的Java&#xff0c;然后确定jdk&#xff0c;然后next 3.这里直接点next 4.写好项目名称和路径…

互联网系统的微观与宏观架构

互联网系统的架构设计&#xff0c;通常会根据项目的体量、业务场景以及技术需求被划分为微观架构&#xff08;Micro-Architecture&#xff09;和宏观架构&#xff08;Macro-Architecture&#xff09;。这两者的概念与职责既独立又相互关联。本文将通过一些系统案例&#xff0c;…

Vue3 学习笔记(五)Vue3 模板语法详解

在 Vue3 的世界里&#xff0c;模板语法是我们构建用户界面的基石。今天&#xff0c;让我们一起深入了解 Vue3 的模板语法&#xff0c;我将用通俗易懂的语言和实用的例子&#xff0c;带你掌握这项必备技能。 1、文本插值&#xff1a;最基础的开始 想在页面上显示数据&#xff1f…

《探索 HarmonyOS NEXT(5.0):开启构建模块化项目架构奇幻之旅 —— 模块化基础篇》

从无到有&#xff0c;打造模块化项目。构建一个开箱即用的项目&#xff0c;从 Git 上拉取下来即可直接进行开发&#xff0c;其中涵盖路由通信、上下拉刷新、网络请求、事件通知、顶部tab封装等功能&#xff0c;项目里调用API为鸿洋大佬的wanAndroidAPI。后期将持续完善&#xf…

【C】数组(array)

数组(array) 数组的概念 数组是一组相同类型元素的集合 数组中存放的是1个或者多个数据&#xff0c;但是数组元素个数不能为0数组中存放的多个数据&#xff0c;类型是相同的 数组分为一维数组和多维数组&#xff0c;多维数组一般比较多见的是二维数组 一维数组的创建和初始…

JAVA面试八股文(五)

#1024程序员节&#xff5c;征文# 在1024程序员节这个特别的日子里&#xff0c;首先&#xff0c;我想对每一位程序员表示最诚挚的祝贺&#xff01;祝愿大家在未来的日子里&#xff0c;能够继续热爱编程、追求卓越&#xff0c;携手共创更美好的科技未来&#xff01;让我们共同庆祝…

Redis Search系列 - 第六讲 基准测试 - Redis Search VS. MongoDB VS. ElasticSearch

目录 一、引言二、Redis Search 2.x版本的性能提升三、Redis Search VS. MongoDB VS. ElasticSearch3.1 测试环境3.2 100%写 - 基准测试3.3 100%读 - 基准测试3.4 混合读/写/搜索 - 基准测试2.5 搜索延迟分析3.6 读延迟分析3.7 写延迟分析3.8 Redis Search VS. ElasticSearch3.…

混个1024勋章

一眨眼毕业工作已经一年了&#xff0c;偶然进了游戏公司成了一名初级游戏服务器开发。前两天总结的时候&#xff0c;本来以为自己这一年没学到多少东西&#xff0c;但是看看自己的博客其实也有在进步&#xff0c;虽然比不上博客里的众多大佬&#xff0c;但是回头看也算是自己的…

micro-app【微前端实战】主应用 vue3 + vite 子应用 vue3+vite

micro-app 官方文档为 https://micro-zoe.github.io/micro-app/docs.html#/zh-cn/framework/vite 子应用 无需任何修改&#xff0c;直接启动子应用即可。 主应用 1. 安装微前端框架 microApp npm i micro-zoe/micro-app --save2. 导入并启用微前端框架 microApp src/main.ts …

手机摄影入门

感觉会摄影的人是能够从生活中发现美的人。 我不太会拍照&#xff0c;觉得拍好的照片比较浪费时间&#xff0c;而且缺乏审美也缺乏技巧&#xff0c;所以拍照的时候总是拍不好。但有时候还是需要拍一些好看的照片的。 心态和审美可能需要比较长时间提升&#xff0c;但一些基础…

Apple Vision Pro市场表现分析:IDC最新数据揭示的真相

随着AR/VR技术逐渐成熟并被更多消费者接受,2024年第二季度(Q2)成为这一领域的一个重要转折点。根据国际数据公司(IDC)发布的最新报告,整个AR/VR市场在本季度经历了显著的增长。接下来,我们将深入探讨Apple Vision Pro在这股增长浪潮中的具体表现。 市场背景 2024年Q2,…

中航资本:股票支撑位和压力位什么意思?股票如何找支撑与压力?

股票支撑位和压力位什么意思&#xff1f; 支撑位是指股票价格在下跌过程中遇到的一个或多个价格方位&#xff0c;这些价位上存在着较强的买盘力气&#xff0c;可以提供满足的支撑&#xff0c;阻止股价继续下跌。 而股票压力位是指股票价格在上涨过程中遇到的一个或多个价格方…

docker部署rustdesk

文章目录 一.ubuntu修改ssh端口二.开放端口三.安装rustDesk四.连接验证 一.ubuntu修改ssh端口 借鉴乌班图Ubuntu 24.04 SSH Server 修改默认端口重启无效 https://bugs.launchpad.net/ubuntu/source/openssh/bug/2069041 sudo vim /etc/ssh/sshd_config sudo systemctl daem…

在windows下利用安装docker加vscode调试OceanBase,

文章目录 一、安装WSL二、安装docker三、 OceanBase安装 -- 运行镜像&#xff0c;配置VScode四、 OceanBase安装 -- 将获取到的文件与docker容器 映射连接 – 参考官方文档 docker安装 在windows上通过docker配置环境并利用vscode调试代码 一、安装WSL 1.可以在任务管理器中&…

⌈ 传知代码 ⌋ 农作物病害分类(Web端实现)

&#x1f49b;前情提要&#x1f49b; 本文是传知代码平台中的相关前沿知识与技术的分享~ 接下来我们即将进入一个全新的空间&#xff0c;对技术有一个全新的视角~ 本文所涉及所有资源均在传知代码平台可获取 以下的内容一定会让你对AI 赋能时代有一个颠覆性的认识哦&#x…