TCP 建链(三次握手)和断链(四次握手)
TCP 建链(三次握手)和断链(四次挥手)
- 背景
- 简介
- 建链(三次握手)
- 断链(四次挥手)
- 序号及标志位
- 延伸问题
- 为什么建立连接需要握手三次,两次行不行?
- 三次握手可以携带数据吗?
- 为什么释放连接是四次,比建立连接多一次?
- 为什么 `TIME_WAIT` 状态需要经过 `2MSL` 才能返回到 `CLOSED` 状态?
背景
随着年龄的增长,很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来,技术出身的人总是很难放下一些执念,遂将这些知识整理成文,以纪念曾经努力学习奋斗的日子。本文内容并非完全原创,大多是参考其他文章资料整理所得,感谢每位技术人的开源精神。
简介
本文介绍 TCP 的建链和断链过程,即通常所说的三次握手和四次挥手的过程。
建链(三次握手)
TCP 建链需要客户端与服务器之间交互 3 个数据包,主要作用就是为了确认双方的接收和发送能力是否正常,初始序列号、交换窗口大小以及 MSS 等信息。

-
第一次握手
客户端发送请求连接数据包到服务器,标志位SYN置为1,随机生成一个初始序号seq,即SYN=1 seq=x,客户端从CLOSED状态进入SYN_SENT状态,等待服务器回复。 -
第二次握手
服务器收到请求数据包后根据标志位SYN=1知道客户端在请求建立连接,服务器将标志位SYN和ACK都置为1,确认序号ack=x+1,随机生成一个初始序号seq=y,并将该数据包SYN=1, ACK=1, seq=y, ack=x+1回复给客户端确认连接请求,服务器从LISTEN状态进入SYN_RCVD状态。 -
第三次握手
客户端收到确认后检查确认序号ack是否为x+1,ACK是否为1,如果正确则将标志位ACK置为1,确认序号ack=y+1,并将该数据包ACK=1, seq=x+1, ack=y+1发送给服务器,发送完成后客户端进入ESTABLISHED状态,服务器接收到后检查确认序号ack是否为y+1,如果正确则连接建立成功,服务器进入ESTABLISHED状态。随后客户端与服务器间可以开始传输数据。
断链(四次挥手)

-
第一次挥手
客户端发起FIN包FIN=1, ACK=1, seq=u, ack=v,客户端从ESTABLISHED状态进入FIN_WAIT_1状态。TCP 协议规定,即使FIN包不携带数据,也要消耗一个序号。此FIN包中ACK=1和ack=v基于断链前正常通信的数据包。 -
第二次挥手
服务器收到FIN包,发出ACK确认包,并带上自己的序号seq=v(ACK=1 seq=v ack=u+1),服务器进入从ESTABLISHED状态进入CLOSE_WAIT状态。此时客户端已经没有数据需要发送给服务器了,但服务器如果仍有数据发送给客户端的话,客户端依然需要接收。客户端接收到服务器发送的ACK后进入FIN_WAIT_2状态。 -
第三次挥手
服务器数据发送完成后向客户端发送FIN包FIN=1, ACK=1, seq=w, ack=u+1,半连接状态下服务器可能又发送了一些数据,假设发送seq为w,服务器进入LAST_ACK状态。 -
第四次挥手
客户端接收到服务器的FIN包后发出确认包ACK=1, seq=u+1, ack=w+1,客户端进入TIME_WAIT状态,此时 TCP 连接还没有释放,必须经过2*MSL后才进入CLOSED状态,而服务器接收到客户端的ACK后就进入了CLOSED状态,服务器结束 TCP 连接的时间要比客户端早一些。
序号及标志位
TCP 建链(三次握手)和断链(四次挥手)中涉及到几个关键概念字段:
- 标志位:共有 6 个,分别是:
ACK:确认序号有效。FIN:释放一个连接。PSH:接收方应该尽快将这个报文交给应用层。RST:重置连接。SYN:发起一个新连接。URG:紧急指针(urgent pointer)有效。
seq:Seq 序号,占32位,用来标识从 TCP 源端向目的端发送的字节流,发起方发送数据时对此进行标记。ack:Ack 序号,占32位,只有ACK标志位等于1时此序号字段才有效,确认方ack等于发起方seq + 1。注意:ACK和ack是两个不同的概念,不要混淆了。
延伸问题
为什么建立连接需要握手三次,两次行不行?
- 原因一:TCP连接建立前需要确认客户端和服务器双方的收发包能力。
- 第一次握手可以让服务器知道客户端的发送能力是正常的。
- 第二次握手可以让客户端知道服务器的接收和发送能力都是正常的。
- 第三次握手可以让服务器指导客户端的接收能力是正常的。
- 原因二:确保序列号可靠同步。
第二次握手服务器向客户端发送了自己的初始序列号,如果第二次握手报文丢失则客户端就无法知道服务器的初始序列号,所以需要第三次握手让服务器知道客户端已确认服务器的初始序列号。 - 原因三:阻止重复历史连接的初始化。
客户端由于某种原因发送了两个不同序号的SYN包,因为复杂的网络环境中旧的数据包有可能先到达服务器,如果是两次握手则服务器收到旧的SYN包就会立刻建立连接,从而造成网络异常。如果是三次握手,服务器需要回复SYN+ACK包,客户端会对比应答的序号,如果发现是旧的报文就会给服务器发RST包,直至正确的SYN包到达服务器后才正常建立连接。 - 原因四:安全问题。
TCP 新建连接时内核会为连接分配一系列内存资源,如果采用两次握手可能会放大DDOS 攻击。
三次握手可以携带数据吗?
第一次握手和第二次握手不可以携带数据,第三次握手可以携带数据。假如第一次握手携带数据,如果碰到恶意攻击,那么每次在第一次握手的 SYN 报文中都会加入大量数据,会造成服务器花费大量存储空间来缓存这些数据。
为什么释放连接是四次,比建立连接多一次?
建立连接时服务器的 SYN 和 ACK 是合并发送的,而因 TCP 是全双工通信,释放连接过程中在客户端发送 FIN 包后,服务器可能还有数据需要发送,不能立即关闭连接,所以不能同时发送 FIN 包和 ACK 包,只能先确认 ACK,然后等服务器无数据发送时再发送 FIN 包。
为什么 TIME_WAIT 状态需要经过 2MSL 才能返回到 CLOSED 状态?
MSL 是指报文在网络中的最大生存时间。
- 原因一:在客户端回复服务器
FIN包的确认包ACK后,这个ACK包可能是不可达的,如果服务器收不到ACK的话需要重新发送FIN包。所以客户端发送ACK后需要留出2MSL时间(ACK到达服务器的时间 + 服务器重发FIN包时间),如果客户端等到2MSL后没有收到服务器重传的FIN包,说明可以确认服务器已经收到了客户端发送的ACK包。 - 原因二:客户端发送完最后一个
ACK包后,再经过2MSL时间就可以使当前连接持续的时间内所产生的所有报文都从网络中小时,使下一个新的连接中不会出现这种旧的连接请求报文。
相关文章:
TCP 建链(三次握手)和断链(四次握手)
TCP 建链(三次握手)和断链(四次挥手) 背景简介建链(三次握手)断链(四次挥手)序号及标志位延伸问题为什么建立连接需要握手三次,两次行不行?三次握手可以携带数…...
SpringBoot集成JOOQ加Mybatis-plus使用@Slf4j日志
遇到个问题记录下,就是SpringBoot使用Mybatis和Mybatis-plus时可以正常打印日志,但是JOOQ的操作日志确打印不出来? 下面的解决方法就是将JOOQ的日志单独配置出来,直接给你们配置吧! 在项目的resources目录下创建日志…...
浅谈JavaScript中的对象赋值
目录 常见的对象赋值方式 直接赋值和对象扩展(浅拷贝)两种赋值方式区别 区别 联系 常见的对象赋值方式 1. 直接赋值:this.info this.deviceInfo,将一个对象的引用赋给另一个变量,它们引用同一个对象。 2. 对象扩…...
Java面试题-集合
Java面试题-集合 1、什么是集合?2、集合和数组的区别是什么?3、集合有哪些特点?4、常用的集合类有哪些?5、List, Set, Map三者的区别?6、说说集合框架底层数据结构?7、线程安全的集合…...
从当当网批量获取图书信息
爬取当当网图书数据并保存到本地,使用request、lxml的etree模块、pandas保存数据为excel到本地。 爬取网页的url为: http://search.dangdang.com/?key{}&actinput&page_index{} 其中key为搜索关键字,page_index为页码。 爬取的数据…...
python爬虫之JS逆向——网页数据解析
目录 一、正则 1 正则基础 元字符 基本使用 通配符: . 字符集: [] 重复 位置 管道符和括号 转义符 转义功能 转义元字符 2 正则进阶 元字符组合(常用) 模式修正符 re模块的方法 有名分组 compile编译 二、bs4 1 四种对象 2 导航文档树 嵌套选择 子节点、…...
VL53L4CX TOF开发(2)----修改测距范围及测量频率
VL53L4CX TOF开发.2--修改测距范围及测量频率 概述视频教学样品申请完整代码下载测距范围测量频率硬件准备技术规格系统框图应用示意图生成STM32CUBEMX选择MCU串口配置IIC配置 XSHUTGPIO1X-CUBE-TOF1app_tof.c详细解释测量频率修改修改测距范围 概述 最近在弄ST和瑞萨RA的课程…...
C++之noexcept
目录 1.概述 2.noexcept作为说明符 3.noexcept作为运算符 4.传统throw与noexcept比较 5.原理剖析 6.总结 1.概述 在C中,noexcept是一个关键字,用于指定函数不会抛出异常。如果函数保证不会抛出异常,编译器可以进行更多优化,…...
Kafka之Broker原理
1. 日志数据的存储 1.1 Partition 1. 为了实现横向扩展,把不同的数据存放在不同的 Broker 上,同时降低单台服务器的访问压力,我们把一个Topic 中的数据分隔成多个 Partition 2. 每个 Partition 中的消息是有序的,顺序写入&#x…...
RabbitMQ docker安装及使用
1. docker安装RabbitMQ docker下载及配置环境 docker pull rabbitmq:management # 创建用于挂载的目录 mkdir -p /home/docker/rabbitmq/{data,conf,log} # 创建完成之后要对所创建文件授权权限,都设置成777 否则在启动容器的时候容易失败 chmod -R 777 /home/doc…...
篇3:Mapbox Style Specification
接《篇2:Mapbox Style Specification》,继续解读Mapbox Style Specification。 目录 Spec Reference Root 附录: MapBox Terrain-RGB...
C#WPF数字大屏项目实战11--质量控制
1、区域划分 2、区域布局 3、视图模型 4、控件绑定 5、运行效果 走过路过,不要错过,欢迎点赞,收藏,转载,复制,抄袭,留言,动动你的金手指,财务自由...
第九十七节 Java面向对象设计 - Java Object.Finalize方法
Java面向对象设计 - Java Object.Finalize方法 Java提供了一种在对象即将被销毁时执行资源释放的方法。 在Java中,我们创建对象,但是我们不能销毁对象。 JVM运行一个称为垃圾收集器的低优先级特殊任务来销毁不再引用的所有对象。 垃圾回收器给我们一个…...
【scikit-learn009】异常检测系列:单类支持向量机(OC-SVM)实战总结(看这篇就够了,已更新)
1.一直以来想写下机器学习训练AI算法的系列文章,作为较火的机器学习框架,也是日常项目开发中常用的一款工具,最近刚好挤时间梳理、总结下这块儿的知识体系。 2.熟悉、梳理、总结下scikit-learn框架OCSVM模型相关知识体系。 3.欢迎批评指正,欢迎互三,跪谢一键三连! 4.欢迎…...
网络管理与运维
文章目录 网络管理与运维概念:传统网络管理:基于SNMP集中管理:基于iMaster NCE的网络管理:传统网络管理方式: 基于SNMP集中管理:交互方式:MIB:版本:SNMPv3配置网管平台&a…...
数据库查询字段在哪个数据表中
问题的提出 当DBA运维多个数据库以及多个数据表的时候,联合查询是必不可少的。则数据表的字段名称是需要知道在哪些数据表中存在的。故如下指令,可能会帮助到你: 问题的处理 查找sysinfo这个字段名称都存在哪个数据库中的哪个数据表 SELEC…...
第 400 场 LeetCode 周赛题解
A 候诊室中的最少椅子数 计数:记录室内顾客数,每次顾客进入时,计数器1,顾客离开时,计数器-1 class Solution {public:int minimumChairs(string s) {int res 0;int cnt 0;for (auto c : s) {if (c E)res max(res, …...
数据结构与算法之Floyd弗洛伊德算法求最短路径
目录 前言 Floyd弗洛伊德算法 定义 步骤 一、初始化 二、添加中间点 三、迭代 四、得出结果 时间复杂度 代码实现 结束语 前言 今天是坚持写博客的第18天,希望可以继续坚持在写博客的路上走下去。我们今天来看看数据结构与算法当中的弗洛伊德算法。 Flo…...
Ubuntu系统设置Redis与MySQL登录密码
Ubuntu系统设置Redis与MySQL登录密码 在Ubuntu 20.04系统中配置Redis和MySQL的密码,您需要分别对两个服务进行配置。以下是详细步骤: 配置Redis密码 打开Redis配置文件: Redis的配置文件通常位于/etc/redis/redis.conf。 sudo nano /etc/redis/redis.c…...
数据库连接池的概念和原理
目录 一、什么是数据库连接池 二、数据库连接池的工作原理 1.初始化阶段: 2.获取连接: 3.使用连接: 4.管理和优化: 三、数据库连接池的好处 一、什么是数据库连接池 数据库连接池(Database Connection Pooling&…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...
Linux系统部署KES
1、安装准备 1.版本说明V008R006C009B0014 V008:是version产品的大版本。 R006:是release产品特性版本。 C009:是通用版 B0014:是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存:1GB 以上 硬盘…...
Qt 事件处理中 return 的深入解析
Qt 事件处理中 return 的深入解析 在 Qt 事件处理中,return 语句的使用是另一个关键概念,它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别:不同层级的事件处理 方…...
go 里面的指针
指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...
