TCP的三次握手和四次挥手及常见面试题

article/2025/10/14 9:55:45

一、前言     

       今天上掘金查看热门文章,发现一篇好文 ★前端 100 问:能搞懂 80% 的请把简历给我 ★ ,此文包含100个前端面试问题,仔细阅读完所有题目后,顿感身中数刀无法呼吸,留下了没有技术的泪水,只好回炉重塑 ~

      文章第16题:谈谈你对TCP三次握手和四次挥手的理解? 这是前端面试频率特别高的一个题目,接下来我们学习一下TCP的三次握手和四次挥手

二、为什么会有TCP/IP协议

        计算机使用者意识到,计算机只是单兵作战并不会发挥太大的作用。只有把它们联合起来,电脑才会发挥出它最大的潜力。于是人们就想方设法的用电线把电脑连接到了一起。但是简单的连到一起是远远不够的,需要定义一些共通的东西来进行交流,TCP/IP就是为此而生。电脑有了这些,就好像学会了外语一样,就可以和其他的计算机终端做自由的交流了。

三、TCP简介

传输层控制协议(TCP Transport Control Protocol),是一种面向连接的、可靠的、基于字节流的传输层通信协议,是为了在不可靠的互联网络上提供可靠的端到端字节流而专门设计的一个传输协议。

记住关键词“面向连接”、“可靠”、“字节流”,这是学习掌握TCP的关键:

  • 面向连接:客户端、服务端交换数据前,需要建立连接
  • 可靠:通过特定机制,在不可靠的网络之上,确保报文准确送达
  • 字节流:数据的最小单位为字节。至于字节中存储内容的含义,由于应用层的程序决定

 

四、TCP报文格式

下面分别对其中的字段进行介绍:

⒈ 源端口(Source Port): 16位,表示数据从哪个进程来,

⒉ 目的端口(Destination Port):16位,表示数据到哪个进程去.

⒊ 序号(Sequence Number): 32位,TCP报文段中的数据部分,每一个字节都有它的序号(递增)。根据控制标志中的SYN是否为1,Sequence Number 表达不同的含义:

  • SYN = 1:当前为连接建立阶段,此时的序号为初始序号(ISN)。当数据传输正式开始时,数据的第一个字节的序号为 ISN + 1
  • SYN = 0:当前报文段中,数据部分的第一个字节的序号。

⒋ 确认序号(Acknowledgment Number): 32位,当控制标志的ACK为1时,表示发送方希望收到的下一个报文段的序号(Sequence Number)。一旦连接建立成功,ACK值一直为1。

⒌ 数据偏移(Data Offset): 4位,TCP报文段的首部长度,单位是word(4字节)。字面含义是:TCP报文段的数据的起始处,距离TCP报文段的起始处 的偏移量。4个字节最大能表示的数字是15,所以首部最大60字节。

⒍ 保留(Reserved): 6位,预留作为后续用途,必须是0。

⒎ 控制标志(Control Bits): 一共有6个控制标志,其中SYN/ACK、FIN/ACK主要用于连接的建立、断开阶段。

  • URG: 当置为1时,表示紧急指针(Urgent Pointer)字段有效;
  • ACK:确认序号字段(Acknowledgment Number)有效;
  • PSH:接收方应立即把这个报文段交给应用层;
  • RST: 重建连接;
  • SYN:同步序号,用于建立连接;
  • FIN: 发送端不再发送数据;

⒏ 窗口大小(Window Size):16位,允许对方发送的数据量。告诉对方自己缓冲区还能容纳多少字节,用来控制对方发送数据的速度。

⒐ 检验和(Checksum):16位,发送端对TCP首部、数据进行CRC运算得出的结果。接收端收到数据后,对接收到的TCP报文段的首部、数据进行CRC运算,并跟TCP首部中的校验和进行对比,确保数据在传输过程中没有损坏。

⒑ 紧急指针(Urgent Pointer):16位,仅在URG=1时才生效,它的值是一个偏移量,和序号字段中的值相加得到紧急数据最后一个字节的序号。

 

五、建立连接 vs 断开连接

TCP是一种面向连接的单播协议,在发送数据前,通信双方必须在彼此间建立一条连接。所谓的“连接”,其实是客户端和服务器的内存里保存的一份关于对方的信息,如ip地址、端口号等。

TCP提供了一种可靠、面向连接、字节流、传输层的服务,采用三次握手建立一个连接。采用四次挥手来关闭一个连接。

六、建立连接 - 三次握手

最开始的时候客户端和服务器都是处于CLOSED状态。主动打开连接的为客户端,被动打开连接的是服务器。

❶ TCP服务器进程先创建传输控制块TCB,时刻准备接受客户进程的连接请求,此时服务器就进入了LISTEN(监听)状态;

❷ TCP客户进程也是先创建传输控制块TCB,然后向服务器发出连接请求报文,这是报文首部中的同步序号SYN=1,同时选择一个初始序列号 seq=x ,此时,TCP客户端进程进入了 SYN-SENT(同步已发送状态)状态。TCP规定,SYN报文段(SYN=1的报文段)不能携带数据,但需要消耗掉一个序号。

❸ TCP服务器收到请求报文后,如果同意连接,则发出确认报文。确认报文中应该 ACK=1,SYN=1,确认号是ack=x+1,同时也要为自己初始化一个序列号 seq=y,此时,TCP服务器进程进入了SYN-RCVD(同步收到)状态。这个报文也不能携带数据,但是同样要消耗一个序号。

❹ TCP客户进程收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=y+1,自己的序列号seq=x+1,此时,TCP连接建立,客户端进入ESTABLISHED(已建立连接)状态。TCP规定,ACK报文段可以携带数据,但是如果不携带数据则不消耗序号。

❺ 当服务器收到客户端的确认后也进入ESTABLISHED(已确认)状态,此后双方就可以开始通信了。

七、断开连接 - 四次挥手

数据传输完毕后,双方都可释放连接。最开始的时候,客户端和服务器都是处于ESTABLISHED状态,然后客户端主动关闭,服务器被动关闭。

❶ 客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。

❷ 服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。

❸ 客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。

❹ 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。

❺ 客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗ *∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。

❻ 服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。

八、抓包解析TCP生命周期

下面为wireshark抓包截图,分为3个部分:1建立连接,2数据传输,3断开连接

【1】建立连接

客户端 —> 服务端:[SYN] Seq=0; 客户端、服务端的初始Seq值其实不是0,截图中展示的0是个相对值,是wireshark为了方便开发者进行抓包分析转化过来的。

② 服务端 —> 客户端:[SYN, ACK] Seq=0, Ack=1;

 客户端 —> 服务端:[ACK] Seq=1, Ack=1

【2】发送数据

数据交换是双向的,这里以服务端的HTTP响应为例子。响应内容较大,被拆成了多个TCP包。整个数据发送的过程,就是服务端向客户端发送数据,客户端向服务端发送确认的过程。

服务端 —> 客户端:Seq=1,TCP数据长度273。也就是说,服务端发送的报文段中,第一个数据字节的序号是1;下一个TCP报文段,第一个数据字节的序号应该是274(1 + 273)。

 服务端 —> 客户端:Seq=274,TCP数据长度1400。也就是说,服务端发送的报文段中,第一个数据字节的序号是274;下一个TCP报文段,第一个数据字节的序号应该是1674(274 + 1400)。

③ 客户端 —> 服务端:Ack=274。表示客户端已经收到序号274之前的所有字节;也就是说,服务端如果继续给客户端发送TCP报文,应该发送序号274及以后的数据。

后面的分析过程同上

【3】断开连接

当服务端收到客户端的断开请求时(FIN=1),服务端在同一个响应包里发送了FIN、ACK,达到了减少一个数据包的效果。

九、常见面试题

【1】创建连接,为什么TCP客户端最后还要发送一次确认呢?

一句话,主要防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。

如果使用的是两次握手建立连接,假设有这样一种场景,客户端发送了第一个请求连接并且没有丢失,只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的浪费。

如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。

【2】三次握手过程中可以携带数据吗?

第一次、第二次握手不可以携带数据,其中一个简单的原因就是会让服务器更加容易受到攻击了。而对于第三次的话,此时客户端已经处于 ESTABLISHED 状态。对于客户端来说,他已经建立起连接了,并且也已经知道服务器的接收、发送能力是正常的了,所以能携带数据也没啥毛病。

 【3】SYN攻击是什么?

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

【4】为什么客户端最后还要等待2MSL?

MSL(Maximum Segment Lifetime)可译为“最长报文段寿命”,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。TCP允许不同的实现可以设置不同的MSL值。

第一,保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度看来,我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。

第二,防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。

【5】为什么建立连接是三次握手,关闭连接确是四次挥手呢?

建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。
而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。

【6】如果已经建立了连接,但是客户端突然出现故障了怎么办?

TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

文章每周持续更新,可以微信搜索「 前端大集锦 」第一时间阅读,回复【视频】【书籍】领取200G视频资料和30本PDF书籍资料


http://chatgpt.dhexx.cn/article/8SOeKs31.shtml

相关文章

TCP协议三次握手过程

常见前端面试题 TCP协议三次握手过程 1.第1次握手 建立连接 客户端向服务器发送的报文SYN包信息中SYN码为1 2.第2次握手 服务器回应客户端,用于接受并连接请求 服务器返给客户端的的报文SYN码和ACK码都为1,也称呼为syn-ack报文信息。 3.第3次握手 客…

简述TCP 三次握手

TCP数据报文结构: 三次握手主要用到了序列号(seq)&确认号(ack)及两个标志位(ACK&SYN): seq:序列号和确认号是tcp传输可靠性的关键部分,序列号的随机取值范围为0-2^32-1 关于为什么不使用固定序列号ack:下一个希望收到的序列号且代表之前序列号传输的数据已…

TCP协议三次握手

一、简介 所谓三次握手(Three-way Handshake),是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。这个过程是发生在客户端调用connect()函数,服务器在调用accept()函数接收的时候。 二、一些概念 ACK: ACK (Acknowledge character&…

详解TCP的三次握手

TCP定义及特点 定义 TCP是一种面向连接(连接导向)的、可靠的基于字节流的传输层通信协议。TCP将用户数据打包成报文段,发送后会启动一个定时器,然后另一端收到的数据进行确认、对失序的数据重新排序、丢弃重复数据 特点 TCP是…

TCP为什么三次握手?

参考:公众号 小林coding 常见回答:三次握手保证双方都具有接受和发送数据的能力。 主要原因: 1. 防止重复历史连接的初始化 2.同步双方初始序列号 3.避免资源的浪费 1. TCP为什么三次握手? 1.1 防止重复历史连接的初始化 序…

【Java】TCP的三次握手和四次挥手

文章目录 一、三次握手三次握手的流程 二、四次挥手认识两个重要的状态 三、总结 一、三次握手 TCP三次握手是一个经典的面试题,它指的是TCP在传递数据之前需要进行三次交互才能正式建立连接,并进行数据传递。(客户端主动发起的)…

什么是TCP的三次握手?

三次握手是指建立一个 TCP 连接时,需要客户端和服务端发送三个数据包的过程。进行三次握手是为了确定双方的接收能力和发送能力是否正常。 刚开始客户端处于 Closed 状态,服务端处于 Listen 状态。 第一次握手: 客户端给服务端发送一个 SY…

TCP 三次握手 四次挥手

三次握手 三次握手过程描述 第一次握手: 客户端发送syn标志位和seq num,向服务器申请建立连接,客户端状态由closed变为syn_send 第二次握手: 服务端返回 syn和ack标志位,ack num以及seq num,确认第一次握手的报文段,…

Go_详解TCP协议三次握手四次挥手

三次握手: 三次握手表示建立通信阶段,在TCP协议中,在发送数据的准备阶段,客户端与服务器之间的三次交互,以保证连接的可靠,由于这种面向连接的特性, TCP协议可以保证传输数据的安全&#xff0c…

一文读懂TCP的三次握手(详细图解)

在学习TCP三次握手的过程前,首先熟悉几个缩写简称: TCB 传输控制块,打开后服务器/客户端进入监听(LISTEN)状态 SYNTCP报文标志位,该位为1时表示发起一个新连接ACKTCP报文标志位,该位为1时&…

TCP的三次握手与四次挥手的全过程

三次握手 (1)第一次握手:建立连接时,客户端发送syn包(seqj)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号。 (2)服…

简述TCP的三次握手过程

TCP握手协议 在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接. 第一次握手:建立连接时,客户端发送syn包(synj)到服务器,并进入SYN_SEND状态,等待服务器确认; SYN:同步序列编号(Synchronize Sequence Numbers) 第二次握…

TCP-三次握手

文章目录 三次握手简单示意图详细分析 一些思考为什么是三次握手?SYN 攻击什么是SYN 攻击?如何防止SYN 攻击?数据包丢失了该怎么办?初始序列号为什么随机产生?为什么 SYN 段不携带数据却要消耗一个序列号呢&#xff1f…

计算机网络之TCP三次握手

文章目录 计算机网络之TCP三次握手1.TCP三次握手过程2.TCP三次握手原因,而不是两次3.TCP三次握手原因,而不是四次4.TCP三次握手能携带数据吗5.三次握手连接阶段,最后一次ACK包丢失,会发生什么6.TCP 握手为什么是三次,为…

网络通信TCP协议三次握手

TCP是什么? TCP(Transmission Control Protocol 传输控制协议)是一种面向连接(连接导向)的、可靠的、 基于IP的传输层协议。TCP在IP报文的协议号是6。TCP是一个超级麻烦的协议,而它又是互联网的基础,也是每个程序员必备的基本功。首先来看看OSI的七层模…

栈溢出实例--笔记三(ret2libc)

栈溢出实例--笔记三(ret2libc) 1、栈溢出含义及栈结构2、ret2libc基本思路3、实战3.1、二进制程序如下3.2、查看栈结构3.3、第一次栈溢出3.4、第二次栈溢出 1、栈溢出含义及栈结构 请参考栈溢出实例–笔记一(ret2text) 栈溢出实例–笔记二&a…

ret2libc3

文章目录 ret2libc31.程序分析2.栈帧设计3.exp编写 ret2libc3 当前的ret2libc3:无system,无”\bin\sh“ 1.程序分析 首先file一下,发现是32位程序: checksec一下,发现没有开启pie ida分析程序: 发现有个Se…

PWN题型之Ret2Libc

文章目录 前言0x1 :使用前提条件0x2 :解题思路0x3 :32位程序libc题型模板0x4 :代码的解析0x5 :64位程序实例 前言 菜鸡总结,如有不对,请不吝赐教。 0x1 :使用前提条件 存在溢出条件…

【PWN · ret2libc】[2021 鹤城杯]babyof

Linux_64的经典ret2libc题目,有必要好好整理总结一下其中的流程和注意点 目录 前言 一、题目重述 二、exp(思考与理解在注释) 三、经验总结 攻击步骤: 注意要点 四、疑问 前言 64位Linux和32位Linux确乎有着关于参数传递上的不同&a…

运行不同版本libc

author: Tamako 先上两个美化的链接,不用zsh的 字体 样式,颜色 成品 切换libc 我的工具机是Ubuntu 18.04。 获取libc版本 这个很容易,通过运行libc就可以直接获取,比如buu的Ubuntu16.04 32位机使用的libc 当然有些libc运行…