【计算机网络】TCP

news2025/3/11 5:16:59

1.基本概念及报文格式

基本概念:

TCP的中文全称为传输控制协议(Transmission Control Protocol),是一种可靠的,面向连接的,基于字节流的传输层通信协议。

报文格式:

序号 :占32⽐特,取值范围0~2^32-1。当序号增加到最后⼀个时,下⼀个序号⼜回到0。⽤来指出本TCP报 ⽂段数据载荷的第⼀个字节的序号。

 确认号:占32⽐特,取值范围0~2^32-1。当确认号增加到最后⼀个时,下⼀个确认号⼜回到0。⽤来指出期望 收到对⽅下⼀个TCP报⽂段的数据载荷的第⼀个字节的序号,同时也是对之前收到的所有数据的确认

 确认标志位ACK: 只有当ACK取值为1时,确认号字段才有效。ACK取值为0时,确认号字段⽆效。TCP规定:在TCP 连接建⽴后,所有传送的TCP报⽂段都必须把ACK置1。 

2.工作原理

建立连接(三次握手)

上图展示了TCP建立连接的大致过程,因为是进行了三次数据交互才建立的连接,所以被形象的称为三次握手。

第一次握手:客户端向服务端发送一个特殊的TCP报文段,就是图中的SYN报文段,当SYN=1表示发起一个连接请求或者继续同步请求,很显然,这里的意思是发起一个连接请求,seq是序列号,client_isn是客户端初始序号,它是由客户随机选择的。SYN报文段被封装在一个IP数据报中,被发送给服务端。

第二次握手:一旦含该SYN报文段的IP数据报到达服务器主机(前提是的确到达了,不然就没后面什么事了),服务器就会从该数据报中提取出SYN报文段,为该TCP连接分配TCP缓存和变量,并向客户端发送允许连接的报文段,其中SYN被置为1,这个的意思应该指的就是继续同步请求了,server_isn是服务端初始序列号,ack指的是确认序列号,表示接收方期望收到对方下一个报文段的第一个数据字节的序号,即对已接收数据的确认 ,所以客户端下一次发送的报文段的序号就是client_isn+1.

第三次握手:

当客户端接收到包含上述字段的报文段后,会完成该连接的资源初始化工作(这些资源在第一次发送 SYN 报文段时就已初步分配)。接着,客户端向服务器发送一个报文段,此报文段是建立 TCP 连接的最后一个报文段。它对服务器允许连接的报文段进行了确认,具体而言,客户端把server_isn+1这个值放到 TCP 报文段首部的确认字段中,以此完成确认操作。这时,SYN 标志位被设置为 0,意味着同步过程结束,双方正式进入ESTABLISHED状态,TCP 连接宣告建立。

连接断开(四次挥手)

天下没有不散的宴席,TCP连接也是如此,参与一条TCP连接的两个线程中的任何一个都能终止该连接.

第一次挥手:客户端向服务端发送一个TCP报文段来请求关闭,其中标志位FIN=1,表示客户端不再发送数据,但是此时仍然能够接收数据。该报文段的序列号为seq即x,在发送完这个报文段后,客户端处于FIN_WAIT_1状态,等待服务端的确认

第二次挥手:当服务端接收到了这段报文后会立即向客户端发送一个ACK确认报文,表示服务端已经收到了它的关闭请求,ack=x+1,表示服务端期望客户端下一次发送的第一个报文的序列号为x+1,服务端发送数据的初始序列号为y,服务端在发送完ACK报文后处于CLOSE_WAIT状态。此时客户端到服务端的连接已经关闭,但服务端到客户端的连接仍然是打开的,服务端可以继续向客户端发送数据,客户端在收到ACK报文后处于FIN_WAIT_2状态

第三次挥手:当服务端处理完需要向客户端发送的数据后,服务器也准备关闭连接,就会向客户端发送一个带有 FIN 标志位的 TCP 报文段,表示服务端不再向客户端发送数据,ack仍然为1,这里的seq假设为z,分为两种情况,当服务端在第二次挥手后又向客户端发送了一串数据后,那么z就等于y加上发送的这些数据的字节数,如果没有发送数据,那么z=y+1,服务器发送完FIN后进入LAST_ACK状态,等待客户端的最后一次确认。

第四次挥手:

客户端在收到了服务端发送的FIN后,客户端会发送一个ACK确认报文,ack为x+1,seq为客户端之前在通信中确定的值,客户端发送完ACK报文后进入TIME_WAIT状态,服务器收到ACK后进入CLOSED状态,完全关闭连接,而客户端要在TIME_WAIT状态等待一段时间,通常是 2 倍的最长报文段寿命(2MSL),以确保服务器能收到 ACK,如果在这个时间内没有收到服务器的重传请求,客户端才进入CLOSED状态,彻底关闭连接。

3.可靠传输

我们都知道TCP的传输是可靠的,那么它是如何实现数据的可靠传输呢,下面来一一讲解。

序列号与确认应答

TCP会给每个发送的字节数据分配一个序列号,这里的序列号就是我们上面提到的seq。序列号的作用是为了标识数据的顺序,使得接收方能够按照正确的顺序将数据组装起来.比如发送方发送三个数据包过来,seq分别是1,101,201,那么说明第一个数据包包含字节1到100,第二个包含101到200,以此类推。

接收方在收到数据后,会向发送方发送确认应答消息,就是之前提到的ACK数据包,这个消息中会包含它已经成功接收的数据的序列号,表示接收方期望接收的下一个数据的序列号。例如,接收方成功接收到序列号为1到100的数据后,会发送一个 ACK,其中的确认号为101,表示希望发送方接下来发送序列号为 101 及以后的数据。

重传机制

超时重传:发送方在发送数据后会启动一个定时器。如果在定时器超时之前没有收到接收方的确认应答,就会认为数据传输失败,然后重新发送数据。超时时间一般会根据网络状况动态调整,以适应不同的网络环境。

快速重传:当接收方发现收到的数据序列号不连续,即出现了丢失数据的情况时,它会立即向发送方发送重复的确认应答,告诉发送方丢失的数据段的序列号。当发送方收到一定数量(通常是 3 个)的重复 ACK 时,就会认为相应的数据段丢失了,不等定时器超时就会立即重传该数据段。

选择性确认

在TCP通信过程中,如果发送序列中间某个数据包丢失(⽐如1、2、3、4、5中的3丢失了),TCP 会通过重传最后确认的分组后续的分组(最后确认的是2,会重传3、4、5),这样原先已经正确传输的 分组也可能重复发送(⽐如4、5),降低了TCP性能。

后来就发展出了SACK(Selective acknowledgment,选择性确认)技术 ,告诉发送⽅哪些数据丢失,哪些数据已经提前收到 使TCP只重新发送丢失的包(⽐如3),不⽤发送后续所有的分组(⽐如4、5)

选项字段:TCP 首部中有一个可选字段用于实现选择性确认。当接收方支持 SACK 时,会在 TCP 连接建立时通过 “允许 SACK” 选项来告知发送方。在数据传输过程中,接收方可以在确认报文中使用 SACK 选项来报告已收到的不连续的数据块。

确认信息:SACK 选项中包含了一系列的块边界信息,用于指示接收方已经正确接收的数据段的范围。例如,接收方收到了数据段 1、2、4、5、7、8,就可以通过 SACK 选项告诉发送方数据段 [1, 2]、[4, 5]、[7, 8] 已成功接收,相当于精确地给发送方提供了接收情况的 “地图”。

发送方操作:发送方接收到带有 SACK 信息的确认报文后,就可以根据这些信息准确地知道哪些数据段需要重传,哪些已经被接收方成功接收,从而避免不必要的重传,提高传输效率。

4.流量控制

TCP 的流量控制主要是通过滑动窗口机制来实现的,目的是确保发送方发送数据的速度不会超过接收方处理数据的能力,防止数据丢失和网络拥塞。

4.1滑动窗口原理

将原理前先要了解什么叫做窗口,在 TCP 中,窗口是指在一段特定时间内,发送方或接收方可以处理的数据量范围。对于发送方来说,发送窗口决定了它可以在未收到确认的情况下连续发送的数据量;对于接收方来说,接收窗口表示其接收缓冲区中当前可用的空间大小,即能够接收和处理的数据量。

随着数据的发送和确认,窗口会在数据序列上 “滑动”。发送方每收到一个确认应答,就可以将发送窗口向前滑动,允许发送更多的数据;接收方每处理完一段数据,接收窗口也会相应地向前滑动,为接收新的数据腾出空间。

4.2窗口大小的确定与调整

接收方通告窗口:接收方会在发送给发送方的 TCP 报文段中,通过窗口字段来告诉发送方自己当前的接收窗口大小。这个窗口大小是根据接收方的接收缓冲区剩余空间、处理能力等因素动态计算出来的。例如,接收方的接收缓冲区总大小为 10KB,当前已经占用了 3KB,那么它可能会将接收窗口大小设置为 7KB,并在 ACK 报文中将这个窗口大小值通告给发送方。

发送方窗口调整:发送方根据接收方通告的窗口大小来调整自己的发送窗口。发送方的发送窗口大小不会超过接收方通告的窗口大小,以确保发送的数据不会超出接收方的处理能力。同时,发送方还会考虑网络拥塞等因素,综合确定最终的发送窗口大小。

动态调整:在数据传输过程中,窗口大小会根据网络状况和双方的处理能力不断动态调整。如果接收方处理数据的速度加快,其接收缓冲区的空闲空间增加,就会增大通告给发送方的窗口大小,允许发送方发送更多的数据;反之,如果接收方处理速度变慢或缓冲区快满了,就会减小窗口大小,让发送方减慢发送速度。

4.3流量控制的具体过程

数据发送与窗口滑动:发送方在发送窗口范围内发送数据,并启动定时器。当发送方收到接收方对已发送数据的确认应答时,根据确认应答中的信息,将发送窗口向前滑动。例如,发送方发送了序列号为 101 到 200 的数据,接收方正确接收后发送 ACK 确认,确认号为 201,发送方收到这个 ACK 后,就可以将发送窗口向前滑动,开始发送序列号为 201 及以后的数据。

窗口关闭与打开:当接收方的接收缓冲区已满时,它会将通告给发送方的窗口大小设置为 0,通知发送方暂停发送数据,这就是所谓的 “窗口关闭”。发送方收到窗口大小为 0 的通告后,会停止发送数据,直到接收方再次发送通告,将窗口大小调整为大于 0 的值,即 “窗口打开”,发送方才能继续发送数据。

糊涂窗口综合征:在某些情况下,如果接收方每次只腾出少量的接收缓冲区空间,就通告发送方发送少量的数据,可能会导致发送方发送很多小的数据包,降低网络效率,这种情况称为 “糊涂窗口综合征”。为了避免这种情况,TCP 采用了一些策略,如接收方在缓冲区有足够空间时才通告发送方发送数据,发送方在发送数据时尽量将数据积累到一定大小再发送等。

4.4特殊情况 

⼀开始,接收⽅给发送⽅发送了0窗⼝的报⽂段,后⾯,接收⽅⼜有了⼀些存储空间,给发送⽅发送 的⾮0窗⼝的报⽂段丢失了,发送⽅的发送窗⼝⼀直为零,双⽅陷⼊僵局。

解决方案 

当发送⽅收到0窗⼝通知时,这时发送⽅停⽌发送报⽂ 并且同时开启⼀个定时器,

隔⼀段时间就发个测试报⽂去询问接收⽅最新的窗⼝⼤⼩

如果接收的窗⼝⼤⼩还是为0,则发送⽅再次刷新启动定时器

5.拥塞控制

5.1概念

 拥塞:在某段时间,若对⽹络中某⼀资源的需求超过了该资源所能提供的可⽤部分,⽹络性能就要 变坏,这种情况就叫作拥塞(congestion)。

拥塞控制是⼀个全局性的过程

 涉及到所有的主机、路由器,以及与降低⽹络传输性能有关的所有因素

是需要靠所有节点共同努⼒的结果

防⽌过多的数据注⼊到⽹络中,使⽹络能够承受现有的⽹络负荷。

相⽐⽽⾔,流量控制是点对点通信的控制

5.2拥塞控制的常⽤算法

⽅法概述

慢开始(slow start,慢启动)、拥塞避免(congestion avoidance)

快速重传(fast retransmit)、快速恢复(fast recovery)

⼏个缩写

cwnd(congestion window):拥塞窗

 rwnd(receive window):接收窗

 18 swnd(send window):发送窗,swnd = min(cwnd, rwnd)

5.2.1慢开始

●cwnd的初始值⽐较⼩,然后随着数据包被接收⽅确认(收到⼀个ACK)

cwnd成倍增⻓(指数级)

轮次 1:发送方 A 的 cwnd 为 100 字节,即可以发送一个 MSS 大小的数据段 M1。发送后等待接收方 B 的确认,B 收到 M1 后,向 A 发送对 M1 的确认。

轮次 2:因为收到了 M1 的确认,根据慢开始算法,发送方 A 的 cwnd 翻倍,变为 200 字节,也就是可以发送两个 MSS 大小的数据,所以 A 发送数据段 M2 和 M3。接收方 B 收到 M2 和 M3 后,一次性确认 M1 到 M3 这三个数据段。

轮次 3:由于收到了 M1 到 M3 的确认,cwnd 再次翻倍,变为 400 字节,此时 A 可以发送 4 个 MSS 大小的数据,即 M4 到 M7。接收方 B 收到后,确认 M4 到 M7 这四个数据段。

后续:按照慢开始算法,下一轮 cwnd 会变为 800 字节,可发送更多的数据段(如 M8、M9 等)。只要 cwnd 不超过接收方的 rwnd(3000 字节),且不触发拥塞控制的其他机制,发送方就可以持续按照慢开始算法增大 cwnd 来发送数据。

5.2.2拥塞避免

ssthresh(slow start threshold):慢开始阈值,cwnd达到阈值后,以线性⽅式增加

拥塞避免(加法增⼤):拥塞窗⼝缓慢增⼤,以防⽌⽹络过早出现拥塞

乘法减⼩:只要⽹络出现拥塞,把ssthresh减为拥塞峰值的⼀半,同时执⾏慢开始算法(cwnd⼜恢复到初始值) 当⽹络出现频繁拥塞时,ssthresh值就下降的很快

5.2.3快重传

接收⽅

 每收到⼀个失序的分组后就⽴即发出重复确认 使发送⽅及时知道有分组没有到达 ⽽不要等待⾃⼰发送数据时才进⾏确认

发送⽅

只要连续收到三个重复确认(总共4个相同的确认),就应当⽴即重传对⽅尚未收到的报⽂段 ⽽不必继续等待重传计时器到期后再重传

 

对于个别丢失的报⽂段,发送⽅不会出现超时重传,也就不会误认为出现了拥塞⽽错误地把拥塞窗 ⼝cwnd的值减为1。实践证明,使⽤快重传可以使整个⽹络的吞吐量提⾼约20%。 

 5.2.4快恢复

 当发送⽅连续收到三个重复确认,说明⽹络出现拥塞

 就执⾏“ 乘法减⼩” 算法,把ssthresh减为拥塞峰值的⼀半

与慢开始不同之处是现在不执⾏慢开始算法,即cwnd现在不恢复到初始值

 ⽽是把cwnd值设置为新的ssthresh值(减⼩后的值) 然后开始执⾏拥塞避免算法(“ 加法增⼤”),使拥塞窗⼝缓慢地线性增⼤

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

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

相关文章

关于tomcat使用中浏览器打开index.jsp后中文显示不正常是乱码,但英文正常的问题

如果是jsp文件就在首行加 “<% page language"java" contentType"text/html; charsetUTF-8" pageEncoding"UTF-8" %>” 如果是html文件 在head标签加入&#xff1a; <meta charset"UTF-8"> 以jsp为例子&#xff0c;我们…

pytest结合allure

Allure 一、文档二、指令三、装饰器3.1 allure.step装饰器3.2 allure.description装饰器3.3 allure.title装饰器3.4 allure.link、allure.issue 和 allure.testcase装饰器3.5 allure.epic、allure.feature 和 allure.story装饰器3.6 allure.severity装饰器 一、文档 allure文档…

vue2升vue3,uniapp兼容鸿蒙app踩坑记录

前提&#xff1a;最近鸿蒙势头很好&#xff0c;公司的 uniapp vue2 项目&#xff0c;要兼容鸿蒙app。就开始了我的uniapp转鸿蒙踩坑之旅&#xff0c;请看下文&#xff08;注意下文都是在uniapp开发基础上&#xff09; 1. 首先鸿蒙开发只支持Vue3&#xff0c;不支持Vue2、不支持…

DeepSeek × 豆包深度整合指南:工作流全解析

DeepSeek 豆包深度整合指南&#xff1a;工作流全解析 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;可以分享一下给大家。点击跳转到网站。 https://www.captainbed.cn/ccc 文章目录 DeepSeek 豆包深度整合指南&#xff1a;工…

海思Hi3516DV300交叉编译opencv

OpenCV是一个开源的跨平台计算机视觉库&#xff0c;支持C、Python等多种语言&#xff0c;适用于图像处理、目标检测、机器学习等任务。其核心由C编写&#xff0c;高效轻量&#xff0c;提供实时视觉处理功能&#xff0c;广泛应用于工业自动化、医疗影像等领域。 1 环境准备 1…

[FE] React 初窥门径(五):React 组件的加载过程(commit 阶段)

1. 回顾 前一篇文章我们看到&#xff0c;ReactDOM.render 总共包含这些步骤&#xff0c; 然后介绍了 performSyncWorkOnRoot 做的事情&#xff0c;它主要做了两件事&#xff0c; renderRootSync 可称之为 render 阶段&#xff1a;创建了一颗 Fiber Tree&#xff08;包含 html …

java环境部署

java环境部署 一、准备工作 jrejdkeclipse jdk下载&#xff1a;21和1.8-----官网&#xff1a;Oracle&#xff1a;Java 下载 |神谕 该处选择要依据自身的系统类型选择下载 idea的下载安装&#xff1a;IntelliJ IDEA | Other Versions 二、安装 三、环境配置 四、使用 五、i…

100天精通Python(爬虫篇)——第115天:爬虫在线小工具_Curl转python爬虫代码工具(快速构建初始爬虫代码)

文章目录 一、curl是什么&#xff1f;二、爬虫在线小工具&#xff08;牛逼puls&#xff09;三、实战操作 一、curl是什么&#xff1f; 基本概念&#xff1a;curl 支持多种协议&#xff0c;如 HTTP、HTTPS、FTP、SFTP 等&#xff0c;可用于从服务器获取数据或向服务器发送数据&a…

python-leetcode-解决智力问题

2140. 解决智力问题 - 力扣&#xff08;LeetCode&#xff09; 这道题是一个典型的 动态规划&#xff08;Dynamic Programming, DP&#xff09; 问题&#xff0c;可以使用 自底向上 的方式解决。 思路 定义状态&#xff1a; 设 dp[i] 表示从第 i 题开始&#xff0c;能获得的最高…

SpireCV荣获Gitee 最有价值开源项目称号

什么是GVP&#xff1f; GVP全称Gitee Valuable Project&#xff0c;意思为Gitee最有价值开源项目。作为GVP称号的获得者&#xff0c;SpireCV在开源社区中展现出了卓越的实力和影响力&#xff0c;为开源软件的发展和推广做出了积极的贡献。 这一荣誉不仅充分肯定了过去阿木实验…

数据结构基础(一)

文章目录 1 数据结构基础1.1 什么是程序&#xff1f;1.2 数据、数据元素、数据项、数据对象1.3 基本的逻辑结构 2 算法效率2.1 时间复杂度2.1.1 循环执行次数2.1.2 大O(n)表示法 2.2 空间复杂度 1 数据结构基础 1.1 什么是程序&#xff1f; ​ 程序 数据结构 &#xff0b; 算…

⭐算法OJ⭐N-皇后问题 II【回溯剪枝】(C++实现)N-Queens II

⭐算法OJ⭐N-皇后问题【回溯剪枝】&#xff08;C实现&#xff09;N-Queens 问题描述 The n-queens puzzle is the problem of placing n n n queens on an n n n \times n nn chessboard such that no two queens attack each other. Given an integer n, return the num…

项目管理工具 Maven

目录 1.Maven的概念 1.1​​​​​什么是Maven 1.2什么是依赖管理 1.3什么是项目构建 1.4Maven的应用场景 1.5为什么使用Maven 1.6Maven模型 2.初识Maven 2.1Maven安装 2.1.1安装准备 2.1.2Maven安装目录分析 2.1.3Maven的环境变量 2.2Maven的第一个项目 2.2.1按照约…

国产编辑器EverEdit - 宏功能介绍

1 宏 1.1 应用场景 宏是一种重复执行简单工作的利器&#xff0c;可以让用户愉快的从繁琐的工作中解放出来&#xff0c;其本质是对键盘和菜单的操作序列的录制&#xff0c;并不会识别文件的内容&#xff0c;属于无差别无脑执行。 特别是对一些有规律的重复按键动作&#xff0c;…

“双碳”背景下,企业应该如何提升能源效率?

在当今竞争激烈的市场环境中&#xff0c;企业不仅需要优化成本&#xff0c;还需积极响应国家的能源政策&#xff0c;减少对环境的影响。提升工业能源效率正是实现这一双重目标的关键。中国近年来大力推进“双碳”目标&#xff08;碳达峰、碳中和&#xff09;&#xff0c;并出台…

文献学习——考虑混合储能系统选择的基于改进蜂群算法的热电联产微网多目标经济优化调度

摘要&#xff1a;在考虑混合储能系统模型选择的基础上&#xff0c;基于改进的人工蜂群算法&#xff08;ABC&#xff09;&#xff0c;建立了冷热电联产微电网经济优化的多目标调度模型。为了对以往研究中的单目标模型进行升级&#xff0c;将模型的优化目标设定为微电网的日发电调…

nnMamba:基于状态空间模型的3D生物医学图像分割、分类和地标检测

摘要 本文提出了一种基于状态空间模型&#xff08;SSMs&#xff09;的创新架构——nnMamba&#xff0c;用于解决3D生物医学图像分割、分类及地标检测任务中的长距离依赖建模难题。nnMamba结合了卷积神经网络&#xff08;CNN&#xff09;的局部特征提取能力与SSMs的全局上下文建…

安科瑞新能源充电桩解决方案:驱动绿色未来,赋能智慧能源

安科瑞顾强 引言 在“双碳”目标与新能源汽车产业高速发展的双重驱动下&#xff0c;充电基础设施正成为能源转型的核心环节。安科瑞电气股份有限公司凭借在电力监控与能效管理领域20余年的技术积淀&#xff0c;推出新一代新能源充电桩解决方案&#xff0c;以智能化、高兼容性…

使用开源OPUS-MT模型进行文本翻译(python)

1. 环境准备 pip install transformers 2. 下载机器翻译模型&#xff1a; 2.1 代码从hugging face平台下载 from transformers import MarianMTModel, MarianTokenizer# 指定模型名称 model_name "Helsinki-NLP/opus-mt-zh-en" # 中译英模型# 下载并保存分词器到…

Elastic如何获取当前系统时间

文章目录 1. 使用 _ingest.timestamp 在 Ingest Pipeline 中获取当前时间2. 使用 Painless Script 获取当前时间3. 使用 now 关键字在查询中获取当前时间4. 使用 date 类型字段的默认值5. 使用 Kibana 的 Dev Tools 查看当前时间6. 使用 date 聚合获取当前时间7. 使用 Elastics…