1.前言

本文以博主在某次前端面试中被问到“什么是TCP协议中的三次握手和四次挥手?”为契机,经过整理教材、百度百科以及他人博客,再结合博主自身的理解,尽可能的以通俗易懂的语言来解释TCP协议中的三次握手和四次挥手的具体过程。

2.TCP连接和断开

客户端与服务端在建立TCP连接时需要经过三次握手才能建立,而断开连接则需要四次挥手。整个过程全览如下图所示:

我知道,直接看此图,相信大多数伙伴是懵逼的,下面我们就分别从建立连接和断开连接进行详细介绍。

3.“三次握手”建立连接

客户端与服务端在建立TCP连接时需要经过三次握手才能建立,其具体过程图解如下图:

上图中间的三个箭头即为三次握手。

官方说明(说也白说,还是不懂)

  • 第一次握手:建立连接时,客户端发送SYN包(SYN=j)到服务器,此时客户端进入SYN_SENT状态,并挂起等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。

  • 第二次握手:当服务器收到客户端发来的SYN包后,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

  • 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态。

至此完成三次握手。
怎么样,懵逼吧,我都说了,这种说明,说了也是白说!

博主说明(通俗易懂)

其实建立连接三次握手的过程跟我们平时打电话的过程是一样样的,我们来看这样一个场景:
某天,隔壁老王给隔壁老张打电话,有如下对话:
老王:天王盖地虎!
老张:天王盖地虎,小鸡炖蘑菇!
老王:小鸡炖蘑菇!
电话接通,老王和老张Blalalala....
下来我们结合上面三次握手的图解仔细分析下这个场景,

  • 首先,老王给老张打电话,老王就是客户端,老张就是服务端。只有老王给老张打了电话,老张才会去接电话,也就是说老张不会主动去找老王,只有老王找老张,老张才会应答老王。
    对应到上图中就是客户端主动打开,服务端在监听等待,只有当客户端主动发起建立连接请求的时候,服务端才会配合客户端进行连接。

  • 老王先说句“天王盖地虎!”,说完后老王等待老张回应,老王进入等待状态。
    这个过程对应于图中第一次握手客户端发送SYN包,发完客户端进入SYN_SENT状态。
  • 老张听到老王的话后,回复老王“天王盖地虎,小鸡炖蘑菇!”在这里有个问题,许多同学会认为老张听到老王的话后应该直接回复“小鸡炖蘑菇”就可以了呀,干嘛还要再把老王的话再说一遍。其实不然,老张之所以要重复老王说的那句“天王盖地虎”,是因为老张得清楚的表明我不但能听到你说话,而且我听的非常准确,你说的是“天王盖地虎”而没有被我听成是“上山打老虎”。
    这个过程就对应于图中第二次握手,当服务端收到客户端发来的SYN包后,服务端将SYN包并加上自己的ACK包一起发给客户端,告诉客户端,我不但能收到你发来的东西,我还收的很完整,没有丢包,不信我把刚收到你发来的包发给你看看。
  • 老王听到老张说的“天王盖地虎,小鸡炖蘑菇!”后,心想“嗯,老张能听到我说话,而且还听得很准确,我也得告诉老张我能听到他说话。”,随后,老王就把老张说的“小鸡炖蘑菇”再说给老张,表示告诉老张我也能听到你说话,而且我也听得很准确哦。
    这个过程就对应于图中第二次握手,当服务端收到客户端发来的SYN包后,服务端将SYN包并加上自己的ACK包一起发给客户端,告诉客户端,我不但能收到你发来的东西,我还收的很完整,没有丢包,不信我把刚收到你发来的包发给你看看。
  • 老王听到老张说的“天王盖地虎,小鸡炖蘑菇!”后,心想“嗯,老张能听到我说话,而且还听得很准确,我也得告诉老张我能听到他说话。”,随后,老王就把老张说的“小鸡炖蘑菇”再说给老张,表示告诉老张我也能听到你说话,而且我也听得很准确哦。
    这个过程就对应于图中的第三次握手,当客户端端收到服务端发来的SYN+ACK包后,客户端将ACK包再发给服务端,告诉服务端,我也能收到你发来的东西,我也收的很完整,没有丢包,不信我也把刚收到你发来的包发给你看看。
  • 当老张听到老王说的“小鸡炖蘑菇”后,老张心想“嗯,老王也能听到我说话”。如此,通过以上过程,老王和老张就知道对方能听到自己说话,接下来就可以Blalalala....

听完这么一分析,是不是豁然开朗!!!

那么问题来了

建立连接一定要握手三次吗?两次握手为什么不行?四次握手为什么不行?
还是以老王给老张打电话场景为例,


先看两次握手:
老王:老张,你能听到我说话吗?(第一次握手)
老张:我能听到,老王,你能听到我说话吗?(第二次握手)
此时,两次握手结束,按理连接已经建立成功,可是老张还不知道老王能不能听到自己说话,所以接下来
老王:我们今天去老刘家打麻将吧
老张:我能听到,老王,你能听到我说话吗?
老王卒。


再看四次握手:
老王:老张,你能听到我说话吗?(第一次握手)
老张:我能听到,老王,你能听到我说话吗?(第二次握手)
老王:我能听到,老张,你能听到我说话吗?(第三次握手)
老张:我能听到。(第四次握手)
老王和老张Blalalal....。

显然,两次握手根本就无法建立连接,而四次握手虽然可以建立连接,但是耗费资源啊

4.“四次挥手”断开连接

由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。断开流程如下图所示:

上图中间的四个箭头即为四次挥手。

官方说明

  • 当准备断开TCP连接时,客户端作为主动关闭方向服务端发送一个FIN,用来关闭客户端到服务端的数据传送,此时客户端进入FIN_WAIT1状态。
  • 服务端接收到这个FIN后,向客户端发回一个ACK确认包,此时服务端进入CLOSE_WAIT状态。
  • 客户端接收到服务端发回的ACK确认包后,进入FIN_WAIT1状态。
  • 服务端关闭与客户端的连接,并发送一个FIN给客户端,此时服务端进入LAST_ACK状态。
  • 客户端收到服务端发来的FIN包后,发回ACK报文确认,然后进入TIME_WAIT连接度断开状态,等2MSL后客户端即可回到CLOSED可用状态了。
  • 服务端接收到ACK后,便进入连接断开状态
    四次挥手只有官方说明没有博主说明,是因为博主还没有相当一个特别恰当的例子来比拟这个过程,等博主想到了再来补上

5.TCP通信十种状态

TCP从连接到断开总共要经历十种状态,如下图:

  1. LISTEN:表示服务端的处于连接监听状态,可以接受来自客户端的连接。
  2. SYN_SENT:这个状态与SYN_RCV相对应,当客户端SOCKET执行CONNECT连接时,它首先发送SYN报文,因此也随即它会进入到了SYN_SENT状态,并等待服务端的发送三次握手中的第2个报文。SYN_SENT状态表示客户端已发送SYN报文。
  3. SYN_RCV:这个状态表示接受到了SYN报文,在正常情况下,这个状态是服务器端的SOCKET在建立TCP连接时的三次握手会话过程中的一个中间状态,很短暂。
  4. ESTABLISHED:客户端/服务端连接建立。
  5. FIN_WAIT_1:该状态是当客户端SOCKET在ESTABLISHED状态时,它想主动关闭连接,向服务端发送了FIN报文,此时该客户端SOCKET即进入到FIN_WAIT_1状态。
  6. CLOSE_WAIT:该状态的含义是表示服务端在等待关闭连接。当客户端关闭SOCKET后发送FIN报文给服务端,服务端毫无疑问地会回应一个ACK报文给客户端,此时服务端则进入到CLOSE_WAIT状态。
  7. FIN_WAIT_2:当客户端处于FIN_WAIT_1状态时,当收到服务端回应ACK报文后,则客户端会立即进入到FIN_WAIT_2状态。
  8. LAST_ACK:该状态是服务端在发送FIN报文后,最后等待客户端的ACK报文。当收到客户端的ACK报文后,也即可以进入到CLOSED可用状态了。
  9. TIME_WAIT:该状态表示客户端收到了服务端的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。
  10. CLOSED:这个状态没什么好说的了,表示连接关闭后回到初始状态。

具体流程

连接之前,服务端处于LISTEN(1)状态,当客户端向服务端发送连接请求SYN后,客户端处于SYN_SENT(2)状态,当服务端收到请求并发送回应SYN+ACK后,服务端处于SYN_RECV(3)状态,当客户端收到服务端的回应后,客户端处于已连接ESTABLISHED(4)状态,并向服务端发送ACK,最后服务端也处于已连接ESTABLISHED(4)状态
断开之前,当客户端向服务端发送断开请求FIN之后,客户端处于FIN_WAIT1(1)状态,服务端收到FIN之后,服务端处于CLOSE_WAIT(2)状态,服务端向客户端发送ACK回应,此时客户端处于FIN_WAIT2(3)状态,服务端也即变为LAST_ACK(4)状态,服务端向客户端发送FIN请求,客户端状态变为TIME_WAIT(5),最后,客户端向服务端回应ACK,客户端和服务端状态都变为CLOSED(6)。

6.结语

至此,TCP连接的三次握手和四次挥手全部总结完了,懂没懂就看个人理解了,反正我也是费了好大劲才理清其中的关系。

揭秘——TCP的三次握手和四次挥手的更多相关文章

  1. TCP的三次握手与四次挥手

    TCP的三次握手与四次挥手 一.TCP(Transmission Control Protocol 传输控制协议) TCP是面向对连接,可靠的进程到进程通信的协议 TCP是提供全双工服务,即数据可在同 ...

  2. 你应该这么理解TCP的三次握手和四次挥手

    前言: TCP协议是计算机的基础,他本身是一个非常非常复杂的协议. 本文只是蜻蜓点水,将从网络基础以及TCP的相关概念介绍开始,之后再将三次握手,四次挥手这些内容来阐述. 最后介绍一些常见问题,并给出 ...

  3. TCP/IP三次握手与四次挥手的正确姿势

    0.史上最容易理解的:TCP三次握手,四次挥手 https://cloud.tencent.com/developer/news/257281 A 理解TCP/IP三次握手与四次挥手的正确姿势http ...

  4. TCP的三次握手与四次挥手详解

    TCP的三次握手与四次挥手是TCP创建连接和关闭连接的核心流程,我们就从一个TCP结构图开始探究中的奥秘  序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序 ...

  5. 【图解】给面试官解释TCP的三次握手与四次挥手-Web运用原理及网络基础

    作者 | Jeskson 来源 | 达达前端小酒馆 轻松了解HTTP协议 为什么要学习网络协议呢?为什么要学习计算机完了呢?显然这很重要,至少能够帮助你找到工作的原因之一,学习网络知识点太多太多,没有 ...

  6. TCP的三次握手与四次挥手笔记

    TCP的三次握手与四次挥手笔记 TCP Flags URG: 紧急指针标志 ACK:确认序号标志 PSH:push标志 RST:重置连接标志 SYN:同步序号,用于建立连接过程 FIN: finish ...

  7. TCP的三次握手与四次挥手理解及面试题

    TCP的三次握手与四次挥手理解及面试题(很全面) 转载自:https://blog.csdn.net/qq_38950316/article/details/81087809 本文经过借鉴书籍资料.他 ...

  8. TCP 的三次握手和四次挥手

    参考资料: 1.TCP的三次握手与四次挥手理解及面试题: 2.Http协议三次握手和四次挥手: 3.TCP通信的三次握手和四次撒手的详细流程(顿悟) 前置: 序号(也称序列号) - Sequence ...

  9. WireShark抓包分析以及对TCP/IP三次握手与四次挥手的分析

    WireShark抓包分析TCP/IP三次握手与四次挥手 Wireshark介绍: Wireshark(前称Ethereal)是一个网络封包分析软件.功能十分强大,是一个可以在多个操作系统平台上的开源 ...

随机推荐

  1. ASP.NET Web API 2系列(二):灵活多样的路由配置

    1. 导言 路由系统是请求消息进入ASP.NET Web API消息处理管道的第一道屏障,其根本目的在于利用注册的路由对请求的URL进行解析以确定目标HTTPController和Action的名称, ...

  2. spring boot通过Jedis来操作redis

    idea中新建spring boot项目,引入jedis依赖 <!-- https://mvnrepository.com/artifact/redis.clients/jedis --> ...

  3. Tomcat部署项目的三个方法

    所需软件安装 要想在Tomcat中部署项目前提是先要搭建好Tomcat,搭建Tomcat就离不开以下软件包的安装配置,本次演示使用Linux平台 1.JDK软件包 JDK是一切java应用程序的基础, ...

  4. Linux上安装jdk1.8和配置环境变量

    前言 Linux 上安装jdk1.8 和配置环境变量,参考相关文档,本人在此总结,操作归纳如下. 第一步:创建jdk安装目录(该/usr/local/src 目录是空的,最好把我们自己下载的放到这,容 ...

  5. Spring Cloud之Hystrix

    在微服务架构中,存在那么多的服务单元,若一个单元出现故障(由于网络原因或者自身原因),就很容易因依赖关系而引发故障的蔓延,最终导致整个系统的瘫痪,这样的架构相较传统架构更加不稳定.为了解决这样的问题, ...

  6. 构造函数语义学——Copy Constructor 篇

    构造函数语义学--Copy Constructor 篇 本文主要介绍<深度探索 C++对象模型>之<构造函数语义学>中的 Copy Constructor 构造函数的调用时机 ...

  7. Qt5教程: (7) 模态/非模态对话框

    模态对话框就是在其没有被关闭之前,用户不能与同一个应用程序的其他窗口进行交互,直到该对话框关闭. 非模态对话框就是在被打开时,用户既可选择和该对话框进行交互,也可以选择同应用程序的其他窗口交互. 1. ...

  8. Oracle11g安装与基本使用

    目录 安装 修改用户密码 配置文件修改 使用PLSQL连接Oracle数据库 如何执行SQL 语句 本教程基于oracle11g和PLSQL进行 下载资源见百度网盘链接:https://pan.bai ...

  9. Intel Sandy Bridge Microarchitecture Events

    This is a list of all Intel Sandy Bridge Microarchitecture performance counter event types. Please s ...

  10. std::to_string

    头文件 #include <string> std::string to_string( int value ); std::string to_string( long value ); ...