【面试八股总结】传输控制协议TCP(一)

参考资料 :小林Coding、阿秀、代码随想录

一、什么是TCP协议

TCP是传输控制协议Transmission Control Protocol

TCP 是面向连接的、可靠的、基于字节流的传输层通信协议。

  • 面向连接的:每条TCP连接杜只能有两个端点,每一条TCP连接只能是点对点的(一对一)
  • 可靠的:可靠交付
  • 基于字节流的
    • TCP中的“流”的概念是流入或流出进程的字节序列
    • 基于字节流:虽然应用程序和TCP的交互是一次一个数据块,但TCP把应用程序交下来的数据仅仅看成是一连串的无结构的字节流
    • TCP不保证接收方应用程序收到的数据块和发送方应用程序所发出的数据块具有对应的大小关系,但是接收方应用程序收到的字节流必须和发送方应用程序发出的字节流完全一样。

二、TCP的连接建立

1. 三报文握手

  • TCP 建立连接的过程叫做握手。
  • 握手需要在客户和服务器之间交换三个 TCP 报文段。称之为三报文握手。
  • 三报文握手主要作用是为了确认通信双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。
  • 采用三报文握手可以防止已失效的连接请求报文段突然又传送到了,因而产生错误。

1) 初始状态:

        客户端处于 closed(关闭) 状态,服务器处于 listen(监听) 状态。

2) 第一次握手:

        客户端给服务器发⼀个 SYN 报⽂,指明客户端的初始化序列号 ISN(c)。此时客户端处于SYN_SEND 状态

        该报文首部的同步位 SYN = 1,初始序号 seq = x,SYN = 1。

        该报文段不能携带数据,但要消耗掉⼀个序号。

3) 第二次握手:

        服务器收到客户端的 SYN 报文之后,以自己的 SYN 报⽂作为应答,并且指定自己的初始化序列号 ISN(s)。同时把客户端的 ISN + 1 作为 ACK 的值,表示已经收到了客户端的 SYN,此时服务器处于 SYN_RCVD 的状态

        在确认报文段中 SYN = 1,ACK = 1,确认号 ack = x + 1,初始序号 seq = y。

4) 第三次握手:

        客户端收到 SYN 报文之后,会发送⼀个 ACK 报⽂,把服务器的 ISN + 1 作为 ACK 的值,表示已经收到了服务端的 SYN 报⽂,此时客户端处于 ESTABLISHED 状态服务器收到 ACK 报⽂ 之后,也处于 ESTABLISHED 状态,此时,双方已建立起了连接。

        确认报文段 ACK = 1,确认号 ack = y + 1,序号 seq = x+1(初始为 seq = x,第⼆个报文段所以要+1)

        该ACK报文段可以携带数据,不携带数据则不消耗序号。

2. 为什么需要三次握手?

1) 阻止重复历史连接的初始化

        网络阻塞时,客户端向服务器发送两次SYN请求报文,旧的SYN报文先到达服务器,服务器回复一个ACK+SYN报文,客户端根据自身上下文判断这是一个历史连接(序列号过期或者超时),那么客户端就会发送RST报文给服务端,终止这次连接,服务器收到RST报文后,释放连接。这样新的SYN报文到达后,客户端与服务器就可以正常进行三次握手。

        若采用两次握手,服务器在收到SYN报文后,进入ESTABLISHED状态,服务器并不知道这是历史连接,直接与客户端建立并向客户端发送数据,造成资源浪费,但是客户端会判定这次连接是历史连接,忽略客户端确认消息,也不发送数据,服务端一直等待客户端发送数据。

2) 同步双方初始序列号

TCP协议的通信双方,都必须维护一个序列号,序列号是可靠传输的一个关键因素。

  • 接收端 -> 去除重复元素 ,并且按照序列号顺序接收数据
  • 发送端 -> 确认发送的数据包哪些已经被收到

三次握手确认初始化序列过程:

  • 第一次握手:客户端发送携带客户端初始化序列号的SYN报文;
  • 第二次握手:服务器发送携带服务器初始化序列号以及客户端初始化序列号+1的ACK + SYN应答报文,表示收到客户端SYN报文;
  • 第三次握手:客户端发送携带服务器初始化序列号+1的ACK应答报文。

        两次握手只能保证服务器成功接收了客户端的初始化序列号,但无法确认服务器的初始化序列号是否被成功接收。

3. 半连接队列

        半连接队列(SYN队列)⽤于存放已经发送了 SYN(同步)包,但还未完成三次握⼿的连接。服务器第⼀次收到客户端的 SYN 之后,就会处于 SYN_RCVD 状态,此时双⽅还没有完全建⽴其连接,服务器会把此种状态下请求连接放在⼀个队列⾥,我们把这种队列称之为半连接队列。

        全连接队列(Accept队列)⽤于存放已经完成三次握⼿,处于完全建⽴连接状态的连接。

4. 三次握手可以携带数据吗?

        三次握手中,第一次和第二次连接不可以携带数据,第三次连接可以携带数据。主要原因是如果第一次握手如果携带数据,会让服务器更加容易被攻击,但是第一次握手会消耗一个序列号,对于第三次握手,客户端已经处于ESTABLISHED状态,确认服务器接收、发送能力没有问题,可以发送数据。

5. SYN洪泛攻击

        SYN攻击指Client在短时间内伪造大量不存在的IP地址,并向Server不断发送SYN包,Server则回复确认包,等待Client确认。由于源地址不存在,因此Server需要不断重新发送直到超时,这些伪造的SYN包会长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而导致网络拥塞甚至系统瘫痪。

        检测SYN攻击:在服务器上发现大量半连接状态,特别其源地址IP是随机的,基本确认为SYN攻击。Linux系统下可使用 netstats 命令检测:

netstat -n -p TCP | grep SYN_RECV

防御SYN攻击:

  • 缩短超时(SYN Timeout)时间

  • 增加最大半连接数

  • 过滤网关防护

  • SYN Cookies技术

 三、TCP的连接释放

1. 四报文挥手

  • 数据传输结束后,通信的双方都可释放连接。
  • TCP 连接释放过程是四报文握手。
  • TCP的半关闭(half-close):TCP提供了连接的⼀端在结束它的发送后还能接收来⾃另⼀端数据的能力
  • 客户端和服务器均可以主动发起挥手。

1) 初始状态:

        双方都处于 ESTABLISHED 状态 (假设客户端发起挥手)

 2) 第一次挥手:

        客户端发送⼀个 FIN 报⽂,报⽂中会指定⼀个序列号(FIN=1,序号seq=u)。此时客户端停止再发送数据,主动关闭TCP连接,进⼊FIN_WAIT1状态,等待服务端的确认。

 3) 第二次挥手:

        服务端收到以后,向客户端发送ACK应答报文,且把客户端的 序列号值+1 作为 ACK 报文的序列号值(ACK=1,确认号ack=u+1,序号seq=v),表明已经收到客户端的报文,服务器处于 CLOSE_WAIT 状态,此时TCP处于半关闭状态,客户端到服务端的连接释放。

        客户端收到服务端的确认后,进⼊FIN_WAIT2状态,等待服务端发出的连接释放报文段。

 4) 第三次挥手:

        如果服务器也想断开连接了,和客户端的第⼀次挥手⼀样,发出 FIN 连接释放报文(FIN=1,ACK=1,序号seq=w,确认号ack=u+1),且指定⼀个序列号。此时服务器处于LAST_ACK 的状态,等待客户端的确认。

 5) 第四次挥手

        客户端收到 FIN 之后,发送⼀个 ACK 报文作为应答,且把服务器的序列号值 +1 作为自己 ACK 报文的确认号值(ACK=1,seq=u+1,ack=w+1),客户端处于 TIME_WAIT 状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,客户端才进入CLOSED状态。

        服务端收到 ACK 报文之后,就处于关闭连接了,处于 CLOSED 状态

2. 为什么需要四次挥手?

        关闭连接时,客户端发送FIN报⽂,表示其不再发送数据,但还可以接收数据。服务端收到FIN报文,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是⽤来同步的。但是关闭连接时,服务端可能还有数据需要处理和发送,所以先回⼀个ACK应答报文,等到其不再发送数据时,才发送 FIN报文给客户端表示同意关闭连接。

        服务端通常需要等待完成数据的发送和处理,所以服务端的ACK和FIN⼀般都会分开发送,因此需要四次挥手。

3. 为什么TIME_WAIT状态时间为2MSL?

1)MSL是Maximum Segment Lifetime,可译为“最长报文段寿命”,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。

2)网络中可能存在发送方的数据包,当这些发送方的数据包被接收方处理后⼜会向对方发送响应,所以⼀来⼀回需要等待 2 倍的时间。

3)1 个 MSL 确保四次挥手中主动关闭方最后的 ACK 报文最终能达到对端;1 个 MSL 确保对端没有收到 ACK 重传的 FIN 报文可以到达

2MSL 的时间是从客户端接收到 FIN 后发送 ACK 开始计时的。如果在 TIME-WAIT 时间内,因为客户端的 ACK 没有传输到服务端,客户端又接收到了服务端重发的 FIN 报⽂,那么 2MSL 时间将重新计时

4. 为什么需要 TIME_WAIT 状态(2MSL状态)?     

1) 防止历史连接中的数据,被后面相同四元组的连接错误的接收

        如果网络出现拥塞或延迟,数据包可能会在网络中滞留⼀段时间,甚⾄超过了原始连接关闭的时间。如果没有 TIME_WAIT 状态,客户端直接进入到CLOSE状态,这些滞留的数据包可能会被传递给新连接,导致新连接的数据被旧连接的数据干扰。经过 2MSL 这个时间,足以让两个方向上的数据包都被丢弃,使得原来连接的数据包在网络都自然消失,再出现的数据包⼀定都是新建立连接所产生的。

2) 保证被动关闭连接的⼀方能被正确的关闭,即保证最后的 ACK 能让被动关闭方接收,从而帮助其正常关闭。

        如果最后的⼀次ACK报文丢失(第四次挥手),客户端没有 TIME_WAIT 状态,直接进⼊ClOSE,服务端⼀直在等待 ACK状态,⼀直没有等到,就会重发FIN报文,客户端已经进入到关闭状态,在收到服务端重传的 FIN 报⽂后, 就会回 RST 报文,服务端收到这个 RST 并将其解释为⼀个错误,。为了防止这种情况出现,客户端必须等待足够长的时间,确保服务端能够收到 ACK,如果服务端没有收到 ACK,那么就会触发 TCP 重传机制,服务端会重新发送⼀个 FIN,这样⼀去⼀来刚好两个 MSL 的时间。

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

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

相关文章

js中的事件循环

浏览器进程模型 在理解什么叫事件循环前,我们需要先知道浏览器的进程模型 现代浏览器的功能极度复杂,为了能确保各个部分独立运行互不影响,浏览器会在启动之时开启多个进程,具体而言可以分为以下三种 浏览器进程 负责浏览器的用…

Pulsar服务端处理消费者请求以及源码解析

引言 处理读写是Pulsar服务端最基本也是最重要的逻辑,今天就重点看看服务端是如何处理的读请求也就是消费者请求 正文 Pulsar服务端处理消费者请求的流程大致如下图所示 消费者通过TCP向服务端发起消息拉取请求Broker会根据请求中携带的ID来获取在服务端对应的…

Lua 和 Love 2d 教程 二十一点朴克牌 (上篇lua源码)

GitCode - 开发者的代码家园 Lua版完整原码 规则 庄家和玩家各发两张牌。庄家的第一张牌对玩家是隐藏的。 玩家可以拿牌(即拿另一张牌)或 停牌(即停止拿牌)。 如果玩家手牌的总价值超过 21,那么他们就爆掉了。 面牌…

WIFI|软体 茶凳浅谈 高通WIN QSDK - IPQ6000 与 88Q2112 的相遇

Qualcomm IPQ 系列的Ethernet IC 搭配的有 QCA8075, QCA8081 … 等等Qualcomm自家出产的芯片。QSDK中内建可以支持的3rd party芯片,却寥寥可数。日前,客户使用车载以太网 - 88Q2112 - Marvell与IPQ6000做搭配。将之记录下来,以供参考。 方…

传输层 --- TCP (下篇)

目录 1. 超时重传 1.1. 数据段丢包 1.2. 接收方发送的ACK丢包 1.3. 超时重传的超时时间如何设置 2. 流量控制 3. 滑动窗口 3.1. 初步理解滑动窗口 3.2. 滑动窗口的完善理解 3.3. 关于快重传的补充 3.4. 快重传和超时重传的区别 4. 拥塞控制 4.1. 拥塞控制的宏观认识…

2024年华为OD机试真题-推荐多样性-Java-OD统一考试(C卷)

题目描述: 推荐多样性需要从多个列表中选择元素,一次性要返回N屏数据(窗口数量),每屏展示K个元素(窗口大小),选择策略: 1. 各个列表元素需要做穿插处理,即先从…

新版HI3559AV100开发注意事项(三)

新版HI3559AV100开发注意事项(三) 十九、用的sdk是Hi3559V200_MobileCam_SDK_V1.0.1.5 播放AAC音频文件,adec->ao;adec的初始化里面包括了aaclc解码器的注册,可是在HI_MPI_ADEC_RegisterDecoder(&s32Handle, &stAac);…

一篇文章带你学会7大基本算法(2024最新保姆级教程)

🏠个人主页:尘觉主页 文章目录 算法 - 排序约定选择排序冒泡排序插入排序希尔排序归并排序1. 归并方法2. 自顶向下归并排序3. 自底向上归并排序 快速排序1. 基本算法2. 切分3. 性能分析4. 算法改进4.1 切换到插入排序4.2 三数取中4.3 三向切分 5. 基于切…

vue 打包 插槽 inject reactive draggable 动画 foreach pinia状态管理

在Vue项目中,当涉及到打包、插槽(Slots)、inject/reactive、draggable、transition、foreach以及pinia时,这些都是Vue框架的不同特性和库,它们各自在Vue应用中有不同的用途。下面我将逐一解释这些概念,并说…

用 Wireshark 解码 H.264

H264,你不知道的小技巧-腾讯云开发者社区-腾讯云 这篇文章写的非常好 这里仅做几点补充 init.lua内容: -- Set enable_lua to false to disable Lua support. enable_lua trueif not enable_lua thenreturn end-- If false and Wireshark was start…

Vue使用高德地图(快速上手)

1.在高德平台注册账号 2.我的 > 管理管理中添加Key 3.安装依赖 npm i amap/amap-jsapi-loader --save 或 yarn add amap/amap-jsapi-loader --save 4.导入 AMapLoade import AMapLoader from amap/amap-jsapi-loader; 5.直接上代码,做好了注释(初…

单细胞RNA测序(scRNA-seq)SRA数据下载及fastq-dumq数据拆分

单细胞RNA测序(scRNA-seq)入门可查看以下文章: 单细胞RNA测序(scRNA-seq)工作流程入门 单细胞RNA测序(scRNA-seq)细胞分离与扩增 1. NCBI查询scRNA-seq SRA数据 NCBI地址: https…

前视声呐目标识别定位(六)-代码解析之目标截图并传输

前视声呐目标识别定位(一)-基础知识 前视声呐目标识别定位(二)-目标识别定位模块 前视声呐目标识别定位(三)-部署至机器人 前视声呐目标识别定位(四)-代码解析之启动识别模块 …

51单片机实验02- P0口流水灯实验

目录 一、实验的背景和意义 二、实验目的 三、实验步骤 四、实验仪器 五、实验任务及要求 1,从led4开始右移 1)思路 ①起始灯 (led4) ②右移 2)效果 3)代码☀ 2,从其他小灯并向右依…

服务器设置了端口映射之后外网还是访问不了服务器

目录 排查思路参考: 1、确认服务是否在运行 2、确认端口映射设置是否正确 3、使用防火墙测试到服务器的连通性 4、检查服务内部的配置 5、解决办法 6、学习小分享 我们在一个完整的网络数据存储服务系统设备中都会存有业务服务器、防火墙、交换机、路由器&a…

【Laravel】09 用模型批量赋值简化代码 数据库关系

【Laravel】09 用模型批量赋值简化代码 & 数据库关系 1. 用模型批量赋值简化代码2. 数据库关系 1. 用模型批量赋值简化代码 原来存储一个值 2. 数据库关系 这里可以看到两个SQL是一样的

STM32之HAL开发——不同系列SPI功能对比(附STM32Cube配置)

不同系列STM32——SPI框图 F1系列框图 F4系列框图 TI模式时序图特性 F7系列框图 H7系列框图 注意:F7系列以及H7系列支持Quad-SPI模式,可以连接单,双或者四条数据线的Flash存储介质。 SPI——Cube配置流程 RCC时钟源配置 SYS系统调试模式配…

Spring 详细总结

文章目录 第一章 IOC容器第一节 Spring简介1、一家公司2、Spring旗下的众多项目3、Spring Framework①Spring Framework优良特性②Spring Framework五大功能模块 第二节 IOC容器概念1、普通容器①生活中的普通容器②程序中的普通容器 2、复杂容器①生活中的复杂容器②程序中的复…

MySQL、Oracle查看字节和字符长度个数的函数

目录 0. 总结1. MySQL1.1. 造数据1.2. 查看字符/字节个数 2. Oracle2.1. 造数据2.2. 查看字符/字节个数 0. 总结 databasecharbyteMySQLchar_length()length()Oraclelength()lengthB() 1. MySQL 1.1. 造数据 sql drop table if exists demo; create table demo (id …

Cesium 批量种树

1、准备树种建模 分各种级别建模LOD1-LODN 其中meta.json长这样: Gltf再3Dmax中导出Obj,再通过ObjToGltf的工具转换,参考 https://editor.csdn.net/md/?articleId96484597 2、准备shp点数据。(shp中的点位就是种树的位置) 3、准…