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

一、什么是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 的时间。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mysql实战--为什么表数据删掉一半,表文件大小不变

经常会有同学来问我,我的数据库占用空间太大,我把一个最大的表删掉了一半的数据,怎么表文件的大小还是没变? 那么今天,我就和你聊聊数据库表的空间回收,看看如何解决这个问题。 这里,我们还是针…

Day78:服务攻防-数据库安全RedisCouchDBH2database未授权访问CVE漏洞

目录 前置知识 数据库应用-Redis-未授权访问&CVE漏洞 未授权访问:CNVD-2015-07557 未授权访问-CNVD-2019-21763 未授权访问-沙箱绕过RCE-CVE-2022-0543 数据库应用-Couchdb-未授权越权&CVE漏洞 Couchdb 垂直权限绕过(CVE-2017-12635&…

每天五分钟计算机视觉:如何基于滑动窗口技术完成目标的检测?

汽车检测算法 现在我们想要构建一个汽车检测算法,我们希望输入到算法中一张图片,算法就可以帮助我们检测出这张图片中是否有汽车。 数据集 首先创建一个标签训练集,x是样本,y是标签。我们的训练集最好是被剪切过的图片,剪掉汽车以外的部分,使汽车居于中间位置,就是整张…

Wheel Controller 3D

Wheel Controller 3D是Unity内置WheelCollider的完整替代品。它允许更真实的车辆行为、完全定制和3D地面检测。 Wheel Controller 3D是Unity内置WheelCollider的完整替代品。它允许更真实的车辆行为、完全定制和3D地面检测。 如果您正在寻找包含Wheel Controller 3D的完整车辆物…

第十四届蓝桥杯(八题C++ 题目+代码+注解)

目录 题目一(日期统计 纯暴力): 代码: 题目二(01串的熵 模拟): 代码: 题目三(治炼金属): 代码: 题目四(飞机降落 深度…

测试Windows域控制器服务是否运行

测试Windows域控制器服务是否正常运行,可以通过以下几种方法: 检查服务状态: 打开“服务器管理器”(Server Manager)。在左侧导航栏中选择“工具”(Tools),然后打开“服务”&#xf…

Java 变得越来越像 Rust?

随着编程技术的增强和复杂性的提升,许多编程语言也纷纷效仿,Java 也不例外。 另一边,尽管社区内部问题重重,但 Rust 仍逐年获得开发人员的喜爱。这背后都是有原因的:Rust 的编译器让开发人员避免了各种问题。编译器对…

Redis开源协议调整,我们怎么办?

2024年3月20日, Redis官方宣布,从 Redis 7.4版本开始,Redis将获得源可用许可证 ( RSALv2 ) 和服务器端公共许可证 ( SSPLv1 ) 的双重许可,时间点恰逢刚刚完成最新一轮融资,宣布的时机耐人寻味。 Redis协议调整,对云计算…

前端开发的主要语言有哪些?

1、HTML (HyperText Markup Language) 作用:HTML是构建网页内容的基础,是一种标记语言,用来定义网页的结构,如标题、段落、列表、表格、图像、链接等元素。优点:易于学习,广泛兼容,标准化程度高…

分布式全闪占比剧增 152%,2023 年企业存储市场报告发布

近日,IDC 发布了 2023 年度的中国存储市场报告。根据该报告,在 2023 年软件定义存储的市场占比进一步扩大,分布式全闪的增长尤其亮眼,其市场份额从 2022 年的 7% 剧增到 2023 年的 17.7%,增长了 152%。 01 中国企业存…

C++之海量数据处理(位图+布隆过滤器)

前言:在现实中我们经常会碰到问题的数据量特别大的情况,无法将所有数据都加载到内存里面,这个时候,更不要说对数据进行处理了,该怎么办呢? 目录 目录 一,位图 拓展1:如果是要我们…

Linux之用户账号、用户组和与账号有关的系统文件

目录 一、基本介绍 1.用户和用户组 2.UID和GID 二、 账户管理 1.查看用户的UID和GID 2.添加账户 3.删除账号 4.修改账号 5.账户口令 三、分组管理 1.新增用户组 2.删除用户组 3.修改用户组 4.用户组切换 四、与账号有关的系统文件 1./etc/passwd 2./etc/shado…