用最通俗的语言讲解 TCP “三次握手,四次挥手”

目录

一. 前言

二. TCP 报文的头部结构

三. 三次握手

3.1. 三次握手过程 

3.2. 为什么要三次握手

四. 四次挥手

4.1. 四次挥手过程

4.2. 为什么要四次挥手

五. 大白话说

5.1. 大白话说三次握手

5.2. 大白话说四次挥手

六. 总结


一. 前言

    TCP 是一种面向连接的、可靠的、基于字节流的传输层通信协议,在发送数据前,通信双方必须在彼此间建立一条连接。所谓的“连接”,其实是客户端和服务端保存的一份关于对方的信息,如IP 地址、端口号等。TCP 可以看成是一种字节流,它会处理 IP 层或以下的层的丢包、重复以及错误问题。在连接的建立过程中,双方需要交换一些连接的参数。这些参数可以放在 TCP 头部。一个 TCP 连接由一个4元组构成,分别是两个 IP 地址和两个端口号。一个 TCP 连接通常分为三个阶段:连接、数据传输、退出(关闭)。通过三次握手建立一个链接,通过四次挥手来关闭一个连接。当一个连接被建立或被终止时,交换的报文段只包含 TCP 头部,而没有数据。

    所谓“任 TCP 虐我千百遍,我仍待 TCP 如初恋”。“不管面试 Java 、C/C++、Python 等开发岗位, TCP 的知识点可以说是的必问的了。我们都知道TCP是面向连接的,三次握手就是用来建立连接的,四次挥手就是用来断开连接的。

二. TCP 报文的头部结构

在了解 TCP 连接之前先来了解一下 TCP 报文的头部结构:

TCP Header

上图中有几个字段需要重点介绍下:
(1)序号:seq 序号,占32位,用来标识从 TCP 源端向目的端发送的字节流,发起方发送数据时对此进行标记。
(2)确认序号:ack 序号,占32位,只有 ACK 标志位为1时,确认序号字段才有效,ack=seq+1。
(3)标志位:共6个,即 URG、ACK、PSH、RST、SYN、FIN 等,具体含义如下:

  1. ACK:确认序号有效。
  2. FIN:释放一个连接。
  3. PSH:接收方应该尽快将这个报文交给应用层。
  4. RST:重置连接。
  5. SYN:发起一个新连接。
  6. URG:紧急指针(urgent pointer)有效。需要注意的是:不要将确认序号 ack 与标志位中的ACK 搞混了。确认方 ack= 发起方 seq+1,两端配对。

三. 三次握手

    三次握手的本质是确认通信双方收发数据的能力。首先,我让信使运输一份信件给对方,对方收到了,那么他就知道了我的发件能力和他的收件能力是可以的。于是他给我回信,我若收到了,我便知道我的发件能力和他的收件能力是可以的,并且他的发件能力和我的收件能力是可以。然而此时,他还不知道他的发件能力和我的收件能力到底可不可以,于是我最后回馈一次,他若收到了,他便清楚了他的发件能力和我的收件能力是可以的。这,就是三次握手。

3.1. 三次握手过程 

我们来看一下三次握手的过程:

1. 准备阶段

    一开始,客户端和服务端都处于 CLOSED 状态。客户端主动打开连接,服务端被动打卡连接,结束CLOSED 状态,开始监听,进入 LISTEN 状态。

2. 第一次握手

    客户端会随机初始化序号(client_isn),将此序号置于 TCP 首部的「序号」字段中,同时把 SYN 标志位置为 1 ,表示 SYN 报文。接着把第一个 SYN 报文发送给服务端,表示向服务端发起连接,该报文不包含应用层数据,之后客户端处于 SYN-SENT 状态。

3. 第二次握手

    服务端收到客户端的 SYN 报文后,首先服务端也随机初始化自己的序号(server_isn),将此序号填入 TCP 首部的「序号」字段中,其次把 TCP 首部的「确认应答号」字段填入 client_isn + 1, 接着把 SYN 和 ACK 标志位置为 1。最后把该报文发给客户端,该报文也不包含应用层数据,之后服务端处于 SYN-RCVD 状态。

4. 第三次握手

    客户端收到服务端报文后,还要向服务端回应最后一个应答报文,首先该应答报文 TCP 首部 ACK 标志位置为 1 ,其次「确认应答号」字段填入 server_isn + 1 ,最后把报文发送给服务端,这次报文可以携带客户到服务器的数据,之后客户端处于 ESTABLISHED 状态。

好了,经过三次握手的过程,客户端和服务端之间的确定连接正常,接下来进入 ESTABLISHED 状态,服务端和客户端就可以快乐地通信了。

这里有个动态过程的图示:

这里有个小细节,第三次握手是可以携带数据的,这是面试常问的点。 

3.2. 为什么要三次握手

为什么要三次握手呢?两次不行吗?

  1. 为了防止服务器端开启一些无用的连接增加服务器开销
  2. 防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。

由于网络传输是有延时的(要通过网络光纤和各种中间代理服务器),在传输的过程中,比如客户端发起了 SYN=1 的第一次握手。

如果服务器端就直接创建了这个连接并返回包含 SYN、ACK 和 Seq 等内容的数据包给客户端,这个数据包因为网络传输的原因丢失了,丢失之后客户端就一直没有接收到服务器返回的数据包。

如果没有第三次握手告诉服务器端客户端收的到服务器端传输的数据的话,服务器端是不知道客户端有没有接收到服务器端返回的信息的。服务端就认为这个连接是可用的,端口就一直开着,等到客户端因超时重新发出请求时,服务器就会重新开启一个端口连接。 

这样一来,就会有很多无效的连接端口白白地开着,导致资源的浪费。 

这个过程可理解为:

还有一种情况是:已经失效的客户端发出的请求信息,由于某种原因传输到了服务器端,服务器端以为是客户端发出的有效请求,接收后产生错误:

所以我们需要“第三次握手”来确认这个过程: 
    通过第三次握手的数据告诉服务端,客户端有没有收到服务器“第二次握手”时传过去的数据,以及这个连接的序号是不是有效的。若发送的这个数据是“收到且没有问题”的信息,接收后服务器就正常建立 TCP 连接,否则建立 TCP 连接失败,服务器关闭连接端口。由此减少服务器开销和接收到失效请求发生的错误。

四. 四次挥手

4.1. 四次挥手过程

还是先上图:

四次挥手

聚散终有时,TCP 断开连接是通过四次挥手方式。双方都可以主动断开连接,断开连接后主机中的「资源」将被释放。

上图是客户端主动关闭连接:

第一次挥手:

    客户端打算关闭连接,此时会发送一个 TCP 首部 FIN 标志位被置为 1 的报文,也即 FIN 报文,之后客户端进入 FIN_WAIT_1 状态。

第二次挥手:

    服务端收到该报文后,就向客户端发送 ACK 应答报文,接着服务端进入 CLOSED_WAIT 状态。

第三次挥手:

    客户端收到服务端的 ACK 应答报文后,之后进入 FIN_WAIT_2 状态。等待服务端处理完数据后,也向客户端发送 FIN 报文,之后服务端进入 LAST_ACK 状态。

第四次挥手:

1. 客户端收到服务端的 FIN 报文后,回一个 ACK 应答报文,之后进入 TIME_WAIT 状态;
2. 服务器收到了 ACK 应答报文后,就进入了 CLOSED 状态,至此服务端已经完成连接的关闭;
3. 客户端在经过 2MSL 一段时间后,自动进入 CLOSED 状态,至此客户端也完成连接的关闭。

你可以看到,每个方向都需要一个 FIN 和一个 ACK,因此通常被称为四次挥手

4.2. 为什么要四次挥手

为什么要挥手四次?

再来回顾下四次挥手双方发 FIN 包的过程,就能理解为什么需要四次了。

  1. 关闭连接时,客户端向服务端发送 FIN 时,仅仅表示客户端不再发送数据了但是还能接收数据。
  2. 服务器收到客户端的 FIN 报文时,先回一个 ACK 应答报文,而服务端可能还有数据需要处理和发送,等服务端不再发送数据时,才发送 FIN 报文给客户端来表示同意现在关闭连接。

从上面过程可知,服务端通常需要等待完成数据的发送和处理,所以服务端的 ACK 和 FIN 一般都会分开发送,从而比三次握手导致多了一次。

为什么客户端在 TIME-WAIT 阶段要等 2MSL?

    为的是确认服务器端是否收到客户端发出的 ACK 确认报文,当客户端发出最后的 ACK 确认报文时,并不能确定服务器端能够收到该段报文。

所以客户端在发送完 ACK 确认报文之后,会设置一个时长为 2MSL 的计时器。

MSL 指的是 Maximum Segment Lifetime:一段 TCP 报文在传输过程中的最大生命周期。

2MSL 即是服务器端发出为 FIN 报文和客户端发出的 ACK 确认报文所能保持有效的最大时长。

服务器端在 1MSL 内没有收到客户端发出的 ACK 确认报文,就会再次向客户端发出 FIN 报文:

  • 如果客户端在 2MSL 内,再次收到了来自服务器端的 FIN 报文,说明服务器端由于各种原因没有接收到客户端发出的 ACK 确认报文。

客户端再次向服务器端发出 ACK 确认报文,计时器重置,重新开始 2MSL 的计时。

  • 否则客户端在 2MSL 内没有再次收到来自服务器端的 FIN 报文,说明服务器端正常接收了 ACK 确认报文,客户端可以进入 CLOSED 阶段,完成“四次挥手”。 

所以,客户端要经历时长为 2SML 的 TIME-WAIT 阶段;这也是为什么客户端比服务器端晚进入 CLOSED 阶段的原因。 

这里同样有个动态过程的图示:

四次挥手

五. 大白话说

5.1. 大白话说三次握手

在二十年前的农村,电话没有普及,手机就更不用说了,所以,通信基本靠吼。

老张和老王是邻居,这天老张下地了,结果家里有事,热心的邻居老王赶紧跑到村口,开始叫唤老王:

  1. 老王:老张唉!我是老王,你能听到吗?
  2. 老张一听,是老王的声音:老王老王,我是老张,我能听到,你能听到吗?
  3. 老王一听,嗯,没错,是老张:老张,我听到了,我有事要跟你说。

老王:"你老婆要生了,赶紧回家吧!"

老张风风火火地赶回家,老婆顺利地生了个带把的大胖小子。

握手的故事充满了幸福和美满。

5.2. 大白话说四次挥手

假如博主有一个女朋友——只是“假如”,该死的,这不争气的眼泪,怎么止不住地滴在键盘上。

由于博主上班九九六,下班肝博客,导致没有时间陪女朋友,女朋友忍无可忍:

  • 女朋友:臭男人,最近你都不理我,你是不是不爱我了?你是不是外面有别的狗子了?我要和你分手?
  • 沙雕博主一愣,怒火攻心:分手就分手,不陪你闹了,等我把东西收拾收拾。

沙雕博主小心翼翼地装起了自己的青轴机械键盘:

  • 哼,蠢女人,我已经收拾完了,我先滚为敬,再见!
  • 女朋友:滚,滚的远远的,越远越好,我一辈子都不想再见到你。 

唉,挥手的故事总充满了悲伤和遗憾!

六. 总结

    《TCP/IP详解 卷1:协议》有一张TCP状态变迁图,很具有代表性,有助于大家理解三次握手和四次挥手的状态变化。如下图所示,粗的实线箭头表示正常的客户端状态变迁,粗的虚线箭头表示正常的服务器状态变迁。

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

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

相关文章

【SpringBoot快速入门】(3)SpringBoot整合junit和MyBatis 详细代码示例与讲解

目录 1.SpringBoot整合junit1.1 环境准备1.2 编写测试类 2.SpringBoot整合mybatis2.1 回顾Spring整合Mybatis2.2 SpringBoot整合mybatis2.2.1 创建模块2.2.2 定义实体类2.2.3 定义dao接口2.2.4 定义测试类2.2.5 编写配置2.2.6 测试2.2.7 使用Druid数据源 之前我们已经学习的Spr…

I.MX6ULL_Linux_驱动篇(47)linux RTC驱动

RTC 也就是实时时钟,用于记录当前系统时间,对于 Linux 系统而言时间是非常重要的,就和我们使用 Windows 电脑或手机查看时间一样,我们在使用 Linux 设备的时候也需要查看时间。本章我们就来学习一下如何编写 Linux 下的 RTC 驱动程…

spring boot回顾02

配置文件 SpringBoot使用一个全局的配置文件 , 配置文件名称是固定的 application.properties 语法结构 :keyvalue application.yml 语法结构 :key:空格 value 配置文件的作用 :修改SpringBoot自动配置的默认值&am…

低功耗 电源管理 SCMI接口

SCMI overview: SCMI 协议:

本地websocket服务端结合cpolar内网穿透实现公网访问

文章目录 1. Java 服务端demo环境2. 在pom文件引入第三包封装的netty框架maven坐标3. 创建服务端,以接口模式调用,方便外部调用4. 启动服务,出现以下信息表示启动成功,暴露端口默认99995. 创建隧道映射内网端口6. 查看状态->在线隧道,复制所创建隧道的公网地址加端口号7. 以…

VMware克隆虚拟机

要求:利用模板虚拟机hadoop100,克隆出hadoop101虚拟机。 1、鼠标右键点击已存在的模板虚拟机hadoop100 --> 管理 --> 克隆 2、选择克隆自虚拟机中的当前状态 3、创建完整克隆 4、修改虚拟机名称、位置 5、等待克隆完成后,则成功克隆出…

Debian在升级过程中报错

当我们在升级的过程中出现如下报错信息 报错信息如下所示: The following signatures couldnt be verified because the public key is not available: NO_PUBKEY ED444FF07D8D0BF6 W: GPG error: http://mirrors.jevincanders.net/kali kali-rolling InRelease: …

CentOS安装jdk

1、查看可安装版本 yum -y list java* 2、安装jdk1.8版本 yum -y install java-1.8.0-openjdk 3、查看版本 java -version 4、安装目录为: /usr/lib/jvm 5、卸载 yum -y remove java-1.8.0-openjdk

干洗店预约上门取货小程序与互联网洗鞋店小程序开发制作功能方案

干洗店预约上门取货小程序与互联网洗鞋店小程序开发制作功能方案 一、洗衣洗鞋店小程序功能 1. 预约订单:忙碌时,您可以使用预约功能轻松获取洗衣服务。 2. 在线下单:用户可直接通过小程序在线下单,享受专人上门取货与配送服务。…

Windows下Navicat15.0连接Oracle11g报ORA-28547解决

目录 背景 一、相关环境 1、操作系统 2、Navicat版本 3、ORACLE连接 4、默认连接 二、问题分析 1、默认dll配置 三、修改配置 1、下载匹配的client 2、替换相应目录 总结 背景 最近在项目中需要使用Oracle数据库,当前很多应用系统的数据都存储在MySQL或者Pos…

JRT整合下载文件api

以前最古老的是用的FTP存文件,所以原始的文件操作是直接操作FTP,后面随着使用发现FTP对端口要求太多了,容易出问题,新的安保方面也提安全方面问题,就转http文件服务了。为了同时兼容两种文件服务,此时就抽取…

用户管理第2节课-idea 2023.2 后端一删除表,从零开始---【本人】

一、清空model文件夹下,所有文件 1.1.1效果如下: 1.1代码内容 package com.daisy.usercenter.model;import lombok.Data;Data public class User {private Long id;private String name;private Integer age;private String email; }二、清空mapper文件…

文档理解的新时代:LayOutLM模型的全方位解读

一、引言 在现代文档处理和信息提取领域,机器学习模型的作用日益凸显。特别是在自然语言处理(NLP)技术快速发展的背景下,如何让机器更加精准地理解和处理复杂文档成为了一个挑战。文档不仅包含文本信息,还包括布局、图…

使用 Docker 部署企业培训系统 PlayEdu

1)PlayEdu 介绍 官网:https://www.playedu.xyz/ GitHub:https://github.com/PlayEdu/PlayEdu PlayEdu 是一款适用于搭建内部培训平台的开源系统,旨在为企业/机构打造自己品牌的内部培训平台。PlayEdu 基于 Java MySQL 开发&…

ctfshow sql 195-200

195 堆叠注入 十六进制 if(preg_match(/ |\*|\x09|\x0a|\x0b|\x0c|\x0d|\xa0|\x00|\#|\x23|\|\"|select|union|or|and|\x26|\x7c|file|into/i, $username)){$ret[msg]用户名非法;die(json_encode($ret));}可以看到没被过滤,select 空格 被过滤了,可…

KylinV10 安装 MySQL 教程(可防踩雷)

KylinV10 安装 MySQL 教程(可防踩雷) 1、直接用 apt 快捷安装 MySQL $ sudo apt-get update #更新软件源 $ sudo apt-get install mysql-server #安装mysql然后你会发现,KylinV10 安装畅通无阻,并没有设置密码的场景&#xff0c…

SQLiteStudio安装指南

本博文源于笔者想要打开sqlite3的db文件,于是下载了SQLiteStudio,下载了它,sqlite3的文件随便查看,这里从零开始安装 文章目录 1、搜索官网网址2、开始下载3、开始安装4、开始使用5、总结 1、搜索官网网址 官网地址:…

【Vue中给输入框加入js验证_blur失去焦点进行校验】

【Vue中给输入框加入js验证_blur失去焦点进行校验】 通俗一点就是给输入框加个光标离开当前文本输入框时&#xff0c;然后对当前文本框内容进行校验判断 具体如下&#xff1a; 1.先给文本框加属性 blur“validatePhoneNumber” <el-input v-model“entity.telephone” blur…

挑选办公网盘指南:2023年值得推荐的办公网盘品牌

企业团队在选择办公网盘时&#xff0c;可以通过什么维度进行工具好坏的评判&#xff1f;如何判断网盘的优劣&#xff1f;2023年国内又有哪些值得推荐的网盘品牌呢&#xff1f; 首先是如何选择网盘&#xff1f; 在网盘选择时&#xff0c;我们可以从以下四个方面进行评测&#x…

liunx下用C++使用freetype库在opencv上打中文字

1、/visualizer.cpp:11:10: fatal error: ft2build.h: 没有那个文件或目录 11 | #include <ft2build.h> freetype安装问题&#xff0c;要把文件拉到根目录&#xff0c;不然找不到文件 2、编译失败找不到定义 /usr/bin/ld: CMakeFiles/interactive_face_detection_de…