常见面试题:TCP的四次挥手和TCP的滑动窗口
说一说 TCP 的四次挥手。
挥手即终止 TCP 连接,所谓的四次挥手就是指断开一个 TCP 连接时。需要客户端和服务端总共发出四个包,已确认连接的断开在 socket 编程中,这一过程由客户端或服务端任意一方执行 close 来触发。这里我们假设由客户端主动触发 close。四次挥手的流程如图:

数据传送完毕之后呢,双方都可释放连接。
最开始的时候,客户端和服务端都处于 establish 的状态。然后客户端主动关闭,服务器被动关闭,首先客户端进程发出连接释放报文,并且停止发送数据。在该数据报的报头中呢?TCP flags 中的 finish 就等于1,我们这里假设此时的客户端定义的序列号。为 seq=u, 该值等于前面 establish 状态下数据最后一次发送的时候。已经传送过来的数据的最后一个字节的序号,加上一。此时客户端就进入了 finish wait 1 这么一个终止等待一的状态。TCP 规定。即使并报文段不携带任何数据,也要消耗掉一个序号。回执的时候,它的义务会加一就像这里。那当我们的服务器收到连接释放报文了之后,也要发出确认报文及 ack=1。这里作为回应,我们的小写的 ack,它的 sequence number 也就成为了 u+1。并且也携带上了自己的序列号,就是我们的这个 seq=v。此时服务端就进入了 close wait 这么一个关闭等待的状态。这个状态比较重要,大家呢在这里呢,先留下一个印象 TCP 服务器通知高层的应用进程,客户端要释放跟服务器通信的连接。这时候会处于半关闭的状态,即客户端已经没有数据要发送了,
但是服务器若要发送数据,客户端还是能够接受的。这个状态还要持续一段时间,该时间等于整个 close bay 状态所持续的时间,那客户端收到服务器的确认请求后,也就是第二次挥手的时候呢。此时客户端就进入了 finish wait 2 及终止等待二这个状态。等待服务器发送,释放连接报文,就是等待它发送第三次回收的请求。因此在这段时间内呢,还有可能还需要接受服务器发送的最后的数据,服务器将最后的数据发送完毕后呢。就会向客户端呢发送连接释放报文,这里就是 finish=1, ack 还是等于 u+1。由于在半关闭的状态,服务器很可能又发送了一些数据,此时的序号呢,我们就已经变为了 w。此时服务器就进入了 last ack 的这么一个状态了啊,在发送这个 finish 报文的时候,它就进入了 last ack 及最后确认的状态。等待客户端的最终确认,客户端在收到服务器的连接,释放报文之后必须发出确认。即 ack=1。然后再将服务器发过来的这个 w 变成 w+1 回发回去,通过这个小 ack 回发回去,而自己的序号呢?此时我们假定为 u。那么,它就是 u+1,而自己的序号呢?也就是按照之前的报文的序号加一就是u+1。此时客户端就进入了 time wait。即时间等待的状态,注意此时客户端的 TCP 连接还没有释放,必须经过二乘上 msl 的时间后呢。我们的这个连接才真正的释放,才进入到 close 的状态。MSL 及最长报文段寿命。rfc 793 定义了 msl 的值为两分钟,而 linux 设置成了 30 秒,而咱们的服务器只要收到了客户端发出的确认。立即就进入 close 的状态了,可以看到服务器结束 TCP 的连接时间要比客户端稍早一些。以上便是四次挥手的主要流程。
总结
咱们来总结一下 TCP 采用四次挥手来释放连接,在第一次挥手的过程中呢,client 向 server 呢发送了一个报文。用来关闭 client 到 server 的数据传送。 client 呢,就进入到了 finish wait 1 这么一个状态当中。在第二次挥手的过程中,我们的这个 server 在收到了 client 发来的包文之后。会发送一个 ack 给 client,并且我们的小写的 ack 及确认序号,就是我们之前收到的这个 client 发来的。序号加一。那 server 就会进入到了 close wait 的状态。在第三次挥手的过程中,server 又继续向 client 发送了一个 finish 的数据包。用来关闭 server 到 client 的数据传送。server 就进入了到了 last ack 的状态,那在第四次挥手的过程中,client 在收到 server 发来的 fin 包之后呢?client 就会进入到了摊位状态,接着发送一个 ack 给 server 确认序号。之前收到的这个 server 序号加上一。这我就进入到了 close 状态,那 client 在等待 2 msl 的时间之后也会进入到 close 的状态。从而完成四次挥手。
我们注意到,在 TCP 的四次挥手的状态图中,从 time wait 到 close 状态有一个超时设置。这个超时设置是二乘上 msl。那为什么需要等待这一段时间?为什么不直接给转换成 close 状态?主要有两个原因,第一个原因呢就是time状态呢,它是用来保证有足够的时间让对端收到 ack。如果被动关闭的那方没有收到 ack 呢,就会触发被动端重发 finish 包,一来一去正好是两个msl。第二点就是有足够的时间让这个连接不会跟后面的连接混在一起,因为有些路由器会缓存 IP 数据包。如果连接被重用了,那么这些延迟收到的包呢?就有可能会跟新连接混在一起,
那咱们为什么需要四次回收来中断连接呢?前面我们说过全双工的意思是允许数据在两个方向上同时传输及待同一时间服务器可以发送数据给客户端,客户端也可以发送数据给服务器。而因为 TCP 是全双工的,所以发送方和接收方都需要 finish 报文和 ack 报文,也就是说。发送方和接收方各只需两次挥手即可,只不过有一方是被动的,所以看上去就成了所谓的四次挥手。
TCP滑动窗口
面试过程中经常会被问到TCP 的滑动窗口,想要回答这个问题,咱们先来弄清楚两个 TCP 概念。那就分别是RTT和RTO。
RTT和RTO
- RTT:发送一个数据包到收到对应的ACK,所花费的时间
- RTO:重传时间间隔
再通俗的讲,就是我一开始预先算一个定时器时间,如果你回复了 ack,那重传定时器就自动失效,也就是说不用重传了。如果没有回复给我 ack,然后 RTO 定时器的时间又到了,我就重传,由于 RTO 是本次发送当前数据包所预估的超时时间。那么 RTO 就需要一个很好的算法来统计,来更好的预测这次的超时时间。RTO 不是固定写死的配置,而是经过 RTT 计算出来的。有了 RTT 才能计算出 RTO。基于 RTO,我们便有了重传机制,才能支撑起咱们接下来要介绍的滑动窗口。
TCP使用滑动窗口做流量控制和乱序重排
- 保证TCP的可靠性
- 保证TCP的流控特性
前面我们了解到 TCP 会将数据拆分成段进行发送,出于效率和传输速度的考虑,我们不可能等一段一段数据去发送,等到上一段数据被确认之后再发送下一段数据。这个效率呢是非常低的。
我们是要实现对数据的批量发送。TCP 必须要解决可靠传输以及包乱序的问题。所以 TCP 需要知道网络实际的数据处理带宽或是数据处理速度,这样才不会引起网络拥塞导致丢包。TCP 使用滑动窗口及 sliding window 呢,做流量控制与乱序重排 TCP 的滑动窗口主要有两个作用。
第一个作用是提供 TCP 的可靠性,第二个作用是提供 TCP 的流控特性。前面咱们学习的 TCP 报文头里面呢,有一个字段叫做 window ,我们也可以叫做 advertise window,用于接收方通知发送方自己还有多少缓冲区可以接收数据发送方,根据接收方的处理能力来发送数据不会导致接收方处理不过来。这便是流量控制,同时滑动窗口机制还体现了 TCP 面向自节流的设计思路。咱们来大致了解一下窗口有关数据的计算过程。
窗口数据的计算过程

如图所示,左图是 TCP 协议的发送端缓冲区,而右图是接收端缓冲区。左边往右边发数据,两个图中下面的长方形表示要发送的数据流里面假设装满了数据,并且需要按照顺序从左向右发送或者接收。咱们假设对应的数据段位置序号也是从左到右去增长的,对于发送方来讲呢?lastbyetacked指向收到的连续最大的 ack 的位置,也就是从左端算起,连续已经被接收端的程序呢,发送 ack 回执,确认已收到的这个 sequence number。而 lastbytesend 呢指向已发送的最后一个字节的位置,该位置呢,只是发出去了,但是还没有收到 ack 的回应,而 last byWritten指向上层应用,已写完的最后一个字节的位置及当前程序已经准备好的,需要发送到最新的一个数据段,这段是发送出去,但是还没有收到确认的这段呢,是已经发送出去,并且已经收到接收端的确认了的,我们可以看到从 lastbyeack到 lastbywritten都是没有出现间隔的,都是连续的,对于接收方来讲 last by read 指向上层应用已经读完的最后一个字节的位置,也就说我收到了发送方的数据。并且已经处理,并且给他回执了的数据的最后一个位置,
而 Next by expected 指向收到的连续最大的 sequence 的位置。比如说这段呢,我是已经收到了,但是还没有给你发送回执,而 last by receive 呢,是指向已收到的最后一个字节的位置。可以看到 next by expected 和 last by receive 中间呢,有一些 sequence 还没有到达,对应的是空白的区域。此时,咱们可以根据上面的数值计算出接收方的 advertise window 的大小,
之后呢,回发给发送方,让其计算出。发送方的剩余可发送的数据大小及 effective window 的大小,一个是 advertise window,就我能够接受的窗口,一个是你还可以发送的数据及effective window。此时我们的 advertise window 及接收方还能处理的数据的量是可以通过这个公式来计算的,其中 max receive buffer是指接收方能接收的最大数据量,也可以理解为接收端缓存池的大小。而 last by receive-last by read 就表示的是我们当前接收方已未接收到的数据,或者还没有接收到的.
TCP会话的发送方

滑动原理如图所示了,我们先从原滑动窗口来说起,它是虚线部分组成。前面我们已经知道滑动窗口里面包含了已经发送但是还没有收到接收端的确认的数据,以及还没有发送但是,允许向接收方发送的数据,咱们假设原先的滑动窗口的边界呢?是从 32 到 51。我们假设已发送但未被确认的序号呢是 32 到 40。此时,如果 32 和 33 都没有被确认,而 34 被确认的。咱们的这个窗口也不会向右滑动,只有等到 32 到 34 都被确认之后及连续被确认之后,滑动窗口才会被移动。那在此时,没被移动之前咱们需要大于或者等于 52 的数据及窗口外的数据是不能被发送的。此时,我们假设从 32 到 35 都被确认了,只要滑动窗口会向右移动四位到 36 这个位置的地方。进而我们的程序就能发送后面的 52 到 55 的数据了。对于 TCP 的接收方来讲,在某一时刻,在它的接收缓存内呢,会存在三种状态。
第一种状态是已接收并且已发送回执的状态。第二种是未接收但是可以接收,也就是准备接收的这种状态。第三个是未接收,并且不能接收的状态,因为达到了窗口的预值了,是不能接收的。那由于 ack 直接由 TCP 站回复默认,没有应用延迟,不存在已接收,但是未回复 ack 的这种状态。其中未接收并且准备接收的这一段空间呢,就称为接收窗口了。由于接收窗口的滑动机制和前面发送方的一致,这里我们就不做重复讲解了。
TCP会话的接收方

经过上面的讲解,我们得知 TCP 最基本的传输可靠性来源于确认重传机制。 TCP 的滑动窗口的可靠性也是建立在卷重传基础上的。发送窗口只有收到接收端,对于本段发送窗口内字节的 ack 确认才会移动发送窗口的左边界。接收窗口只有在前面所有的段都确认的情况下才会移动左边界,当在前面还有字节未接收。但收到后面的字节的情况下呢,窗口是不会移动的,并不对后续字节确认,以此确保对端。会对这些数据呢进行重传。以上便是滑动窗口的基本原理,滑动窗口的大小可以依据一定策略动态调整。应用会根据自身的处理能力的变化,通过本端 TCP 接收窗口大小的控制来实现对端的发送窗口进行流量限制。
如果本文对你有帮助,可以关注我,第一时间获取更多精彩文章。读者小伙伴也可以在我的个人网站:程序员波特,获取更多Java相关技术系列教程,共享电子书、Java学习路线、视频教程、简历模板和面试题等学习资源。
相关文章:
常见面试题:TCP的四次挥手和TCP的滑动窗口
说一说 TCP 的四次挥手。 挥手即终止 TCP 连接,所谓的四次挥手就是指断开一个 TCP 连接时。需要客户端和服务端总共发出四个包,已确认连接的断开在 socket 编程中,这一过程由客户端或服务端任意一方执行 close 来触发。这里我们假设由客户端…...
力扣随笔之两数之和 Ⅱ -输入有序数组(中等167)
思路:在递增数组中找出满足相加之和等于目标数 定义左右两个指针(下标)从数组两边开始遍历,若左右指针所指数字之和大于目标数,则将右指针自减,若左右指针所指数字之和小于目标数,则左指针自加&…...
最优传输(Optimal Transport)
最优传输(Optimal Transport)是一种数学理论和计算方法,用于描述两个概率分布之间的距离或者对应关系。它的核心概念是如何以最佳方式将一组资源(如质量、能量等)从一个位置传输到另一个位置。 基本概念: …...
MIT-6.824-Lab2,Raft部分笔记|Use Go
文章目录 前记Paper6:RaftLEC5、6:RaftLAB22AtaskHintlockingstructureguide设计与编码 2BtaskHint设计与编码 2CtaskHint question后记 LEC5:GO, Threads, and Raftgo threads技巧raft实验易错点debug技巧 前记 趁着研一考完期末有点点空余…...
使用openeuler 22.03替代CentOS 7.9,建立虚拟机详细步骤
进入浏览器搜索网址下载openeuler 22.03镜像文件 https://mirrors.huaweicloud.com/openeuler/openEuler-22.03-LTS-SP3/ISO/x86_64/openEuler-22.03-LTS-SP3-x86_64-dvd.iso 打开VMware Workstation新建一个虚拟机: 自定义虚拟机位置 加入下载好的openeuler镜像文件…...
代理技术引领出海征程
在数字娱乐的繁荣时代,游戏开发者和发行商们意识到,要在全球市场立足,必须迈向国际化的出海之路。然而,这一旅程面临着跨越网络壁垒、适应多元文化和提升全球连接性的巨大挑战。本文将深入探讨代理技术在游戏行业出海过程中的创新…...
谷粒商城篇章9 ---- P248-P261/P292-P294 ---- 消息队列【分布式高级篇六】
目录 1 消息队列(Message Queue)简介 1.1 概述 1.2 消息服务中两个重要概念 1.3 消息队列主要有两种形式的目的地 1.4 JMS和AMQP对比 1.5 应用场景 1.6 Spring支持 1.7 SpringBoot自动配置 1.7 市面上的MQ产品 2 RabbitMQ 2.1 RabbitMQ简介 2.1.1 RabbitMQ简介 2…...
【Spring连载】使用Spring Data访问 MongoDB(五)----生命周期事件
【Spring连载】使用Spring Data访问 MongoDB(五)----生命周期事件Lifecycle Events 一、实体回调Entity Callbacks1.1 实现实体回调1.2 注册实体回调 二、特定存储的实体回调 一、实体回调Entity Callbacks 1.1 实现实体回调 1.2 注册实体回调 二、特…...
JavaSec 之 SQL 注入简单了解
文章目录 JDBC 注入语句拼接(Statement)修复方案 语句拼接(PrepareStatement)修复方案 预编译 JdbcTemplate修复方案 MyBatisLike 注入Order By 注入In 注入 寒假学了一个月 pwn,真心感觉这玩意太底层学的我生理不适应了,接下来学一段时间 java 安全缓一…...
第十一章——期约与异步函数
ECMAScript 6及之后的几个版本逐步加大了对异步编程机制的支持,提供了令人眼前一亮的新特性。ECMAScript 6新增了正式的Promise(期约)引用类型,支持优雅地定义和组织异步逻辑。接下来几个版本增加了使用async和await关键字定义异步…...
工具方法合集-utils.js
通用 import get from lodash.get import cloneDeep from lodash.clonedeep // 深度clone export function deepClone(obj) {return obj ? cloneDeep(obj) : obj } export function lodashGet(obj, key, defaultValue = ) {//这个 defaultValue 不能给默认 值 会报错;retur…...
安卓11-设置HDMI分辨率流程
安卓11中从设置-显示设置hdmi分辨率流程:framework层通过jni控制底层驱动实现,标准驱动模型 packages\apps\Settings\src\com\android\settings\display\HdmiSettings.javaprivate void updateResolution(final ITEM_CONTROL control, final int index) {showWaitin…...
Vue3+vite搭建基础架构(11)--- 菜单栏功能和Tab页功能实现
Vue3vite搭建基础架构(11)--- 菜单栏功能和Tab页功能实现 说明删除项目中不需要的文件userStore全局属性代码菜单栏代码Tab页代码解决浏览器输入地址时不会打开tab页问题和切换tab页时参数丢失问题 说明 这里记录下自己在Vue3vite的项目实现菜单栏功能和…...
餐饮神秘顾客公司:关于餐饮行业神秘顾客调查注意事项
在餐饮业,顾客体验往往决定品牌的成败。为深入了解顾客需求和感受,许多餐饮企业引入“神秘顾客”调查。然而,此调查并非简单走过场,其中细节和注意事项颇多。餐饮行业神秘顾客调查需注意以下几点: 1. 专业培训&#x…...
概率密度函数(PDF)与神经网络中的激活函数
原创:项道德(daode3056,daode1212) 在量子力学中,许多现象都是统计的结果,基本上用的是正态分布,然而,从本质上思考,应该还存在低阶的分布,标准的正态分布是它的极限,这样一来,或许在…...
.netcore 6.0/7.0项目迁移至.netcore 8.0 注意事项
1、SqlSugarCore 相关 1.1 主项目添加数据,否则会报数据库连接错误: <InvariantGlobalization>false</InvariantGlobalization> <PropertyGroup><TargetFramework>net8.0</TargetFramework><Nullable>enable</…...
算法打卡day2|数组篇|Leetcode 977.有序数组的平方、 209.长度最小的子数组、59.螺旋矩阵II
算法题 Leetcode 977.有序数组的平方 题目链接: 977.有序数组的平方 大佬视频讲解:977.有序数组的平方 个人思路 第一时间就只想到暴力解法,双重循环一个循环比较一个循环赋值;但这样可能会超时,所以还能用双指针࿰…...
Hive【内部表、外部表、临时表、分区表、分桶表】【总结】
目录 Hive的物种表结构特性 一、内部表 建表 使用场景 二、外部表 建表:关键词【EXTERNAL】 场景: 外部表与内部表可互相转换 三、临时表 建表 临时表横向对比编辑 四、分区表 建表:关键字【PARTITIONED BY】 场景: 五、分桶表 …...
随手写的小程序2 一个nc能控制的程序
小程序源代码 下载: https://download.csdn.net/download/nn_84/88846445?spm1001.2014.3001.5501 请下载 Qt 5.12.12 server.pro : QT gui networkCONFIG c11 console CONFIG - app_bundle# You can make your code fail to compile if it uses deprecated APIs. # In o…...
Android中通过属性动画实现文字轮播效果
前些天发现了一个蛮有意思的人工智能学习网站,8个字形容一下"通俗易懂,风趣幽默",感觉非常有意思,忍不住分享一下给大家。 👉点击跳转到教程 一、创建一个自定义ProvinceView类,具体代码如下 /*** Author: ly* Date: 2024/2/22* D…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
