TCP三次握手和四次挥手详解(面试常见问题)

article/2025/9/15 16:19:57

  大概两个月前,一位朋友在面试360集团时,在面试过程中被问及TCP三次握手和四次挥手的相关知识,他当时只知道大概,但当时面试官问他TCP三次握手过程中发送的数字是多少,他一下子就懵住了,因为这也是他第一次参加面试,准备的并不充分,也根本没想到会问到具体发送的数字,结果显而易见,最后被刷了。由此可见,TCP三次握手和四次挥手在面试中是面试官非常喜欢的问题,所以掌握这个知识是十分重要的。

  TCP是面向连接的协议。运输连接是用来传送TCP报文的。TCP的运输连接有三个过程,即建立连接数据传输连接释放。

  TCP连接建立过程中要解决以下三个问题:

  (1):要使每一方都能够确认对方的存在。

  (2):要允许双方协商一些参数

  (3):能够对运输实体资源进行分配

   TCP连接的建立采用客户机/服务器模式,主动发起连接建立的应用进程叫做客户机,而被动等待连接建立的应用进程叫做服务器。

   TCP的连接建立:

  1.首先,客户机与服务器的TCP进程都处于CLOSED(关闭)状态,当要进行TCP连接时,客户机主动打开连接服务器被动打开连接(这是因为服务请求总是由客户机向服务器发起,因为想要请求的资源都在服务器上,所以客户机想要获取资源就必须主动向服务器发起请求,而不能是等待服务器向自己(客户机)发起请求)。

   2.然后,服务器的TCP进程先创建传输控制块TCB(传输控制块TCB存储了每一个连接中的重要信息,如:TCP连接表,指向发送和接收缓存的指针,指向重传队列的指针,当前的发送和接收序号,等等),此时,服务器就处于LISTEN(收听)状态。同样的,客户机也会首先创建一个传输控制块TCB发送给服务器。这样,准备工作就做好了。

  3.现在就可以开始真正的三次握手了。首先,客户机先向服务器发送连接请求报文段,该报文段中将首部中的同步位SYN置为1(只有当SYN置为1时,才能表明客户机想要和服务器建立连接),并且随机选择一个初始序号x,注意此时的SYN数据报中并没有携带数据,但是仍旧要消耗掉一个序号(意思就是下次客户机发送数据的时候,序号为x+1),此时客户机进入到SYN-SENT(同步已发送)状态。

  4.此时,服务器收到客户机的请求时,如果同意与该客户机进行连接,则需要向客户机发送确认报文。在发送报文中需要将SYN与ACK都置为1(当ACK置为1时,表明服务器同意与客户机进行连接;同时将SYN置为1,表明服务器想要和客户机建立连接),并且随机选择一个初始序号y,确认号为x+1(确认号表明服务器渴望收到的下一个报文段的第一个数据字节的序号,因为之前发送了x,所以下一个序号为x+1),注意此时的SYN数据报中并没有携带数据,但是也要消耗掉一个序号(同样的,也就是说服务器下次发送数据的时候,序号为y+1),此时TCP服务器进程进入到SYN-RCVD(同步收到)阶段。

  顺便提一句,在这两个阶段会发送SYN Flooding攻击,可以看本人另外一篇博客SYN Flooding攻击。

       5.TCP客户端收到服务器的确认后,还要再向服务器给出确认。确认报文段中ACK置为1,确认号为ack=y+1(因为之前服务器给客户机发送的序号为y,因此现在客户机向服务器发送的确认号为ack=y+1,意思是客户机渴望收到的下一个报文段的第一个数据字节为y+1)此时客户机的发送序号为x+1(这是因为刚才刚才客户机向服务器发送连接请求时消耗了序号x,因此此时的序号为x+1)注意:在进行第三次握手时,ACK报文段可以携带数据,也可以不携带数据,如果携带数据,则消耗一个序列,这样客户机下次发送报文段时的序号为x+2,如果不携带数据则不消耗序号,下次客户机发送报文段时的序号为x+1。这时TCP连接已经建立,客户机和服务器都进入到ESTABLISHED(已建立连接)状态。

  其实上面的三次握手实质上就相当于是下列的对话:

-客户机:服务器,我想要和你建立连接,你同意吗?(SYN=1)

-服务器:客户机,我同意和你建立连接(ACK=1);我也想和你建立连接,你同意吗?(SYN=1)

-客户机:服务器,我同意和你建立连接。(ACK=1)

.  其实,在进行第二次握手时(即服务器向客户机进行应答时),可以看作时发了两次包,先回答客户机的服务请求(ACK=1,ack=x+1),然后再向客户机发出请求(SYN=1,seq=y)

常见面试问题:

问:三次握手中,为什么客户机最后还要再向服务器发送一次确认呢?

答:这是为了防止已失效的连接请求报文段突然又传到了服务器。所谓“已失效的连接请求报文段”是这样产生的。考虑一种正常的情况,客户机发出连接请求,但因为连接请求报文丢失而未收到确认。于是客户机再重传了一次连接请求,后来收到了确认,建立了连接。数据传输完后,就释放了连接。客户机共发送了两个连接请求报文段,其中第一个丢失,第二个到达了服务器,没有所谓的“已失效的连接请求报文段”。

  但是如果出现了一种异常情况,即客户机发出的第一个报文段并没有丢失,而是在某个节点上长时间滞留了,直至客户机向服务器发送了第二个报文段并且已经完成数据传输释放了连接,此时,第一个报文到达服务器后会被误以为是客户机重新发起的一次连接请求,实质上是一个早已失效的连接请求。如果没有第三次握手,那么这个连接就建立了,但是客户机并不会向服务器发送任何请求,这样连接就会一直持续,白白的消耗网络资源。

TCP的连接释放:

  1.数据传输结束后,通信的双方都可以释放连接。此时,客户机和服务器都处于ESTABLISHED(已建立连接)状态

  2.假设客户机请求完资源了,想要释放连接。首先,客户机的应用进程先向服务器发出连接释放报文段,该报文段中将首部的终止控制位FIN置为1(只有当FIN置为1时,才能表明客户机想要和服务器断开连接),并且序号为u(注意:此时的u不是随机产生的,而是之前客户机传送的数据的最后一个字节的序号加1。此时客户机进入到FIN-WAIT-1(终止等待1)状态,等待服务器的确认。

  3.服务器收到连接释放报文后发出确认,在发送报文中将首部中的ACK置为1(ACK置为1,表面服务器同意与客户机释放连接),并且产生序号v(注意:此时的v不是随机产生的,而是之前服务器传送的数据的最后一个字节的序号加1),并且发出确认号为u+1(确认号表明服务器渴望收到的下一个报文段的第一个数据字节的序号,因为之前发送了u,所以下一个序号为u+1)。此时服务器就进入CLOSE-WAIT(关闭等待)状态,客户机进入FIN-WAIT-2状态。

        此时,从客户机到服务器这个方向的连接就被释放了,也就是说,客户机已经没有数据要向服务器发送了,但是如果服务器向客户机发送数据,客户机仍要接收数据。也就是说:从客户机到服务器的连接已经被释放了,但是从服务器到客户机的连接还没被释放。此时,TCP连接处于半关闭状态。

        4.如果服务器向客户机也没有要发送的数据的话,那么服务器的应用进程就可以向客户机发出连接释放报文段(注意此时还是服务器向客户机发送数据),该报文段中将首部的终止控制位FIN置为1(只有当FIN置为1时,才能表明客户机想要和服务器断开连接),ACK也置为1,并且序号为w(重点注意,此时的w不一定等于v+1。如果在客户机释放了连接之后,服务器向客户机仍旧发送了一部分数据,那么此时w不等于v+1,但是如果期间没有再发送数据,那么w就等于v+1。总而言之,这个w等于服务器上一次发送的数据的最后一个字节加1),并且发送确认号为u+1(确认号表明服务器渴望收到的下一个报文段的第一个数据字节的序号,因为之前发送了u,所以下一个序号为u+1)。此时服务器就进入了LAST-ACK(最后确认)状态。

       5.客户机收到服务器的连接释放报文后,必须对此报文进行确认。在该报文段中将ACK置为1,确认号为w+1(确认号表明服务器渴望收到的下一个报文段的第一个数据字节的序号,因为之前发送了w,所以下一个序号为w+1),产生序号为u+1(因为上一个发送的数据的序号为u)。此时服务器进入到TIME-WAIT(等待时间)状态。但是,此时TCP连接还没有被释放掉。必须经过2MSL后服务器才能进入到CLOSED状态。(注:MSL叫做最长报文段寿命,RFC建议为两分钟,也就是说,要经过四分钟才能进入到CLOSED状态)。

其实上面的四次挥手实质上就相当于是下列的对话:

-客户机:服务器,我想和你断开连接,你同意吗?(FIN=1)

-服务器:我同意(ACK=1)

(在此期间,服务器可能还会向客户机发送数据,但是客户机却不能再向服务器发送数据)

-服务器:客户机,我想要和你断开连接,你同意吗?(FIN=1)

-客户机:我同意。(ACK=1)

再等待2MSL时间后就真正断开了连接。

常见面试问题:

问:为什么客户机发送完最后一个数据后要在TIME-WAIT状态等待 2MSL(四分钟)的时间呢?

答:第一:为了保证客户机最后发送的那个ACK报文段能够到达服务器。这个ACK报文段可能会丢失。因而使处在LAST-ACK状态的B收不到对已发送的FIN+ACK报文段的确认。服务器会超时重传这个FIN+ACK报文段,而客户机就能在2MSL时间内收到这个重传的FIN+ACK报文段。接着客户机重传一次确认,重新启动2MSL计时器,最后客户机和服务器都可以进入到CLOSED(关闭)状态。如果没有2MSL等待时间,那么就无法收到重传的FIN+ ACK包,无法进入正常的CLOSED状态。

       第二,防止“已失效的连接请求报文段”出现在本连接中。客户机在发送完最后一个ACK报文段,再经过时间2MSL,就可以使本连接持续的时间内所产生的报文段都从网络中消失。这样就可以使下一个新的连接中不会出现这种旧的连接请求报文段。

总结:再三次握手和四次挥手中这些数字都比较重要,最好都记住,以防后面会用到。


http://chatgpt.dhexx.cn/article/GVQ3tuc7.shtml

相关文章

详解TCP 三次握手和四次挥手

任 TCP 虐我千百遍,我仍待 TCP 如初恋。 过去不会没关系,今天就让我们来消除这份恐惧,微笑着勇敢的面对它吧! 1、TCP 基本认识 2、TCP 连接建立 3、TCP 连接断开 4、Socket 编程 TCP 基本认识 瞧瞧 TCP 头格式 我们先来看看 TC…

简述三次握手和四次挥手

三次握手 第一次握手:客户端给服务端发送一个SYN报文,并指明客户端的初始化序列号,此时客户端处于SYN_SENT状态 第二次握手:服务端收到客户端的SYN报文之后,会回复SYN报文作为应答,并且也指定了自己的初始…

TCP三次握手和四次挥手最通俗解释说明

TCP三次握手和四次挥手以及11种状态 1、三次握手 置位概念:根据TCP的包头字段,存在3个重要的标识ACK、SYN、FIN ACK:表示验证字段 SYN:位数置1,表示建立TCP连接 FIN:位数置1,表示断开TCP连接 三…

简述TCP三次握手和四次挥手

为了准确无误地把数据送达目标处,TCP 协议采用了三次握手策略。 1.1 TCP三次握手漫画图解 如下图所示,下面的两个机器人通过 3 次握手确定了对方能正确接收和发送消息(图片来源:《图解 HTTP》)。 简单示意图: 客户端–发送带有 SYN 标志的数据包–一次握手–服务端服务…

tcp三次握手和四次挥手

TCP三次握手与四次挥手详解(最全面) 一、TCP 协议简述 TCP 提供面向有连接的通信传输,面向有连接是指在传送数据之前必须先建立连接,数据传送完成后要释放连接。 无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。在TCP/I…

三次握手和四次挥手详解

详解 TCP 连接的“ 三次握手 ”与“ 四次挥手 ” *TCP connection* 客户端与服务器之间数据的发送和返回的过程当中需要创建一个叫TCP connection(关系,连接)的东西; 由于TCP不存在连接的概念,只存在请求和响应&…

TCP三次握手和四次挥手过程

TCP三次握手和四次挥手过程 1、TCP报文段首部2、TCP三次握手过程及常见问题2.1 TCP三次握手过程2.2 常见问题 3、TCP四次挥手过程及问题3.1 TCP四次挥手过程3.2 常见问题 1、TCP报文段首部 要理解TCP三次握手和四次挥手的过程,首先需要了解TCP报文段的某些首部的含义…

三次握手和四次挥手

三次握手和四次挥手 三次握手四次挥手 ♠ \color{red}{\spadesuit} ♠ ok,上一篇介绍完TCP/IP的常见状态码,对TCP协议有一个大概的了解了,接下来进入TCP协议的(建立连接)三次握手和四次挥手(关闭连接&#…

详解三次握手和四次挥手

三次握手和四次挥手是各个公司常见的考点,也具有一定的水平区分度,也被一些面试官作为热身题。很多小伙伴说这个问题刚开始回答的挺好,但是后面越回答越冒冷汗,最后就歇菜了。 见过比较典型的面试场景是这样的: 面试官&#xff1…

TCP为什么需要3次握手与4次挥手

http://blog.csdn.net/xifeijian/article/details/12777187 为什么需要“三次握手” 在谢希仁著《计算机网络》第四版中讲“三次握手”的目的是“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”。在另一部经典的《计算机网络》一书中讲“三次…

一文搞懂TCP的三次握手和四次挥手

目录 1、三次握手 2、四次挥手 3、11种状态名词解析 TCP的三次握手和四次挥手实质就是TCP通信的连接和断开。 三次握手:为了对每次发送的数据量进行跟踪与协商,确保数据段的发送和接收同步,根据所接收到的数据量而确认数据发送、接收完毕…

【通俗易懂】三次握手与四次挥手

1.三次握手 三次握手(Three-way Handshake)是指在建立一个TCP连接时,客户端和服务器会一共发送三个报文段。 初始时客户端和服务器都处于CLOSED状态,当服务器应用程序创建一个监听套接字时,服务器处于LISTEN状态。 …

面试官,不要再问我三次握手和四次挥手

温馨提示:本篇文章会长期维护及更新,详情见:https://yuanrengu.com/2020/77eef79f.html 面试相关文章推荐: 面试必备 | 小伙伴栽在了JVM的内存分配策略。。。垃圾收集器(CMS、G1)及内存分配策略Java虚拟机…

C语言数据结构创建矩阵,及代入数据

创建一个这样的矩阵 数据由我们插入(定位坐标行列及插入的数据) 代码如下: 思路:将每个坐标节点和我们插入的节点坐标做对比,如果行列坐标都相等,则value置1并输出其相应的数据,否则value还是为0&#x…

数据结构-树(c语言实现篇)

数据结构之二叉树(c语言实现篇) 介绍树的概念和二叉树的概念和应用,内容主要是以二叉树为主。 1. 树 1.1 树的概念 树是n个结点的有限集,当n0时,称为空树。树是一种非线性的数据结构,与前面的线性表、栈和…

c语言的数据结构表达式求值

最近学习c语言的数据结构中有关栈的实现。下面是用栈实现表达式求值的一个实例,用的是顺序栈的形式 原理: List item 我们默认一‘#’开始,最后输入’#‘结束 在运算中的每一步中,任意两个相继出现的算符theta1和theta2之间的关…

C语言数据结构篇——栈的顺序存储

作者名:Demo不是emo 主页面链接:主页传送门创作初心:对于计算机的学习者来说,初期的学习无疑是最迷茫和难以坚持的,中后期主要是经验和能力的提高,我也刚接触计算机1年,也在不断的探索&#xf…

C语言数据结构之查找(顺序查找,折半查找)

C语言数据结构之查找(顺序查找,折半查找) tips:前些天已经学习了树和图的相关知识,今天来总结下两种常用的查找方式(顺序查找,折半查找)。 为了演示方便,顺序查找和折半…

【C语言数据结构7】--串的实现

串 一、什么是串 串就是我们常说的字符串,它同样是一个线性表。可能有人认为串就是元素为字符的线性表,但这种说法是不准确的。对于普通的线性表,它们关注的往往是单个元素,每个单独的元素都有独立的含义。比如我们用线性表存储…

C语言数据结构——查找(检索)

一、查找的基本概念 查找:查询某个关键字是否在(数据元素集合)表中的过程。也称作检索。 查找表: 由同一类型的数据元素(或记录)构成的集合。 主关键字: 能够惟一区分各个不同数据元素的关键字 次关键字: 通常不能惟一区分各个不同数据元素的…