【计算机网络】TCP三次握手,四次挥手以及SYN,ACK,seq,以及握手次数理解

TCP三次握手图解

在这里插入图片描述


描述

  • 第一次握手:客户端请求建立连接,发送同步报文(SYN=1),同时随机一个seq=x作为初始序列号,进入SYN_SENT状态,等待服务器确认

  • 第二次握手:服务端收到请求报文,如果同意建立连接,则发送同步确认报文 (SYN=1,ACK=1),确认号 ack=x+1,随机一个seq=y作为初始序列号,进入SYN_RECV状态

  • 第三次握手:客户端收到服务端确认,发送确认报文(ACK=1),确认号ack=y+1,序列号seq=x+1,双方都进入ESTABLISHED状态,完成三次握手


TCP 三次握手时各标志位(SYN、ACK、ack、seq)的变化

步骤发送方SYNACKseq(序列号)ack(确认号)状态变化
① 第一次握手客户端 → 服务器10x(随机初始值)SYN_SENT(客户端等待服务器回应)
② 第二次握手服务器 → 客户端11y(随机初始值)x+1SYN_RECV(服务器等待客户端确认)
③ 第三次握手客户端 → 服务器01x+1y+1ESTABLISHED(连接建立成功)

各字段含义

  • SYN(同步标志位):用于建立连接,表示请求同步序列号。
  • ACK(确认标志位):表示确认前面接收到的数据。
  • seq(序列号):表示数据包的起始字节编号,保证数据按顺序传输。
  • ack(确认号):告诉对方你下一个数据要发的编号。

SYN 主要用于建立连接,ACK 用于确认数据,seqack 共同维护数据的顺序和完整性。


如何理解 TCP 的 seq(序列号)?

在 TCP 通信中,seq(序列号) 的作用是标识发送的数据字节流的顺序,确保数据包能按序到达,并且防止丢失和重复。


1. 在三次握手中的 seq 具体作用

在 TCP 三次握手 时,每一方都会选择一个随机的序列号 seq,作为自己即将发送数据流的起始编号,具体流程如下:

1️⃣ (第一次握手,客户端 → 服务器)

  • 客户端 选择一个随机的初始序列号 x,并发送:
    SYN=1, seq=x
    
  • 含义:请求建立连接,并告诉服务器,我的初始序列号是 x,从 x 号字节开始传输数据。

2️⃣ (第二次握手,服务器 → 客户端)

  • 服务器 收到请求,同意建立连接,并选择一个自己的初始序列号 y,回复:
    SYN=1, ACK=1, seq=y, ack=x+1
    
  • 含义
    • seq=y:表示服务器选择的初始序列号是 y,数据从 y 号字节开始传输。
    • ack=x+1:告诉客户端:「我已经收到你的 SYN 请求,并确认你的序列号 x,下一次你发送数据时,请从 x+1 开始。」

3️⃣ (第三次握手,客户端 → 服务器)

  • 客户端 收到服务器的确认后,回复:
    ACK=1, seq=x+1, ack=y+1
    
  • 含义
    • seq=x+1:客户端告诉服务器:「我将从 x+1 号字节开始发送数据。」
    • ack=y+1:告诉服务器:「我已经收到你的 SYN 请求,并确认你的序列号 y,你下次发送数据时,从 y+1 开始。」

至此,三次握手完成,双方建立可靠连接,可以开始数据传输。


📌 结论

🔹 TCP 通过 seq(序列号)保证数据按顺序传输,不丢失,不重复,是 TCP 可靠传输的核心机制。
🔹 在三次握手中,seq 主要用于确定双方通信的起始位置,并避免历史连接数据混淆。


为什么需要三次握手,而不是两次?

如果只有两次握手,可能会导致历史连接请求的影响,从而引发服务器资源浪费或错误连接。

假设仅用两次握手:

  1. 客户端发送 SYN(请求建立连接)
  2. 服务器收到后直接发送 SYN-ACK 并建立连接
  3. 但是客户端可能已经超时,不再理会这个连接

这样,服务器会一直等待客户端的数据,导致资源浪费,甚至出现**半连接(Half-Open Connection)**问题。因此,第三次握手(ACK) 能确保客户端确实收到了服务器的回应,并正式建立连接,避免这种情况。

  • 情景:在双方两次握手即可建立连接的情况下,假设客户端发送 A 报文段请求建立连接,由于网络原因造成 A 暂时无法到达服务器,服务器接收不到请求报文段就不会返回确认报文段。

  • 客户端在长时间得不到应答的情况下重新发送请求报文段 B,这次 B 顺利到达服务器,服务器随即返回确认报文并进入 ESTABLISHED 状态,客户端在收到 确认报文后也进入 ESTABLISHED 状态,双方建立连接并传输数据,之后正常断开连接。

  • 此时姗姗来迟的 A 报文段才到达服务器,服务器随即返回确认报文并进入 ESTABLISHED 状态,但是已经进入 CLOSED 状态的客户端无法再接受确认报文段,更无法进入 ESTABLISHED 状态,这将导致服务器长时间单方面等待,造成资源浪费。


为什么是三次,而不是四次?

三次握手让双方确认通信能力:

所谓确认通信能力就是双方都确认对方自己的收发能力正常

  • 在第一次握手 A确认自己可以发,B确认A可以发,自己可以收,发

  • 第二次,A确认自己可以发可以收,B可以收可以发,但是此时B还不能确认A可以收,

  • 所以有了第三次,此时,双方都确认对方自己的收发能力正常

如果是四次握手:

  • 额外的一次确认没有实际意义,因为三次握手已经确保了双方的通信能力。

  • 额外的开销会降低效率,没有必要增加额外的握手步骤。

结论:

  • 两次握手不够安全,可能导致服务器误认为连接已建立。

  • 三次握手足够确保双方都能正常通信,并防止历史连接问题。

  • 四次握手是多余的,没有额外的安全或可靠性提升,因此 TCP 采用三次握手。


TCP四次挥手图解

在这里插入图片描述

描述

  • 第一次挥手:客户端向服务端发送连接释放报文(FIN=1,ACK=1),主动关闭连接,同时等待服务端的确认。
    序列号 seq = u,即客户端上次发送的报文的最后一个字节的序号 + 1
    确认号 ack = k, 即服务端上次发送的报文的最后一个字节的序号 + 1
  • 第二次挥手:服务端收到连接释放报文后,立即发出确认报文(ACK=1),序列号 seq = k,确认号 ack = u + 1。
    这时 TCP 连接处于半关闭状态,即客户端到服务端的连接已经释放了,但是服务端到客户端的连接还未释放。这 表示客户端已经没有数据发送了,但是服务端可能还要给客户端发送数据。
  • 第三次挥手:服务端向客户端发送连接释放报文(FIN=1,ACK=1),主动关闭连接,同时等待 A 的确认。
    序列号 seq = w,即服务端上次发送的报文的最后一个字节的序号 + 1。
    确认号 ack = u + 1,与第二次挥手相同,因为这段时间客户端没有发送数据
  • 第四次挥手:客户端收到服务端的连接释放报文后,立即发出确认报文(ACK=1),序列号 seq = u + 1,确认号为 ack = w + 1。

此时,客户端就进入了 TIME-WAIT 状态。注意此时客户端到 TCP 连接还没有释放,必须经过 2*MSL(最长报文段寿命)的时间后,才进入 CLOSED 状态。而服务端只要收到客户端发出的确认,就立即进入 CLOSED 状态。可以看到,服务端结束 TCP 连接的时间要比客户端早一些。


为什么连接的时候是三次握手,关闭的时候却是四次握手?

服务器在收到客户端的 FIN 报文段后,可能还有一些数据要传输,所以不能马上关闭连接,但是会做出应答,返回 ACK 报文段.

接下来可能会继续发送数据,在数据发送完后,服务器会向客户单发送 FIN 报文,表示数据已经发送完毕,请求关闭连接。服务器的ACK和FIN一般都会分开发送,从而导致多了一次,因此一共需要四次挥手。

为什么客户端的 TIME-WAIT 状态必须等待 2MSL ?

主要有两个原因:

  1. 确保 ACK 报文能够到达服务端,从而使服务端正常关闭连接。

    第四次挥手时,客户端第四次挥手的 ACK 报文不一定会到达服务端。服务端会超时重传 FIN/ACK 报文,此时如 果客户端已经断开了连接,那么就无法响应服务端的二次请求,这样服务端迟迟收不到 FIN/ACK 报文的确认,就无法正常断开连接。

    MSL 是报文段在网络上存活的最长时间。客户端等待 2MSL 时间,也就是两次报文发送时间:
    假设客户端在传最后的ACK报文,但是没有发给服务端,然后服务端在这1MSL中没有接到客户端的ACK报文,于是再次发送FIN报文耗时1MSL打到客户端,刚好2MSL,客户端可以重新回应,而不至于在不等这2MSL的情况下直接关机

    如果服务端重发的 FIN 没有成功地在 2MSL 时间里传给客户端,服务端则会继续超时重试直到断开连接。

  2. 防止已失效的连接请求报文段出现在之后的连接中。

    TCP 要求在 2MSL 内不使用相同的序列号。客户端在发送完最后一个 ACK 报文段后,再经过时间 2MSL,就可以保证本连接持续的时间内产生的所有报文段都从网络中消失。这样就可以使下一个连接中不会出现这种旧的连接请求报文段。或者即使收到这些过时的报文,也可以不处理它。


TIME-WAIT 状态过多会产生什么后果?怎样处理?

  • 服务端: 短时间内关闭了大量的Client连接,就会造成服务器上出现大量的TIME_WAIT连接,严重消耗着服务器的资源,此时部分客户端就会显示连接不上。

  • 客户端:客户端TIME_WAIT过多,就会导致端口资源被占用,因为端口就65536个,被占满就会导致无法创建新的连接。

  • 解决办法

  • 服务端:设置 SO_REUSEADDR 套接字选项来避免 TIME_WAIT状态,此套接字选项告诉内核,即使此端口正忙(处于TIME_WAIT状态),也请继续并
    重用它。

  • 客户端:动态选择不同的源端口,避免因 TIME-WAIT 过多导致端口耗尽


https://github.com/0voice

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

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

相关文章

DVWA -第二关-命令执行

这里是个ping命令的提交框 我们在输入ping命令的时候,同时执行其他命令操作 low 输入127.0.0.||ipconfig 消除乱码的方法:修改dvwaPage.inc.php文件中的”charsetutf-8”,修改”charsetGB2312” 可以显示出来,初级没有过滤 m…

Kibana:Spotify Wrapped 第二部分:深入挖掘数据

作者:来自 Elastic Philipp Kahr 我们将比以往更深入地探究你的 Spotify 数据并探索你甚至不知道存在的联系。 在由 Iulia Feroli 撰写的本系列的第一部分中,我们讨论了如何获取 Spotify Wrapped 数据并在 Kibana 中对其进行可视化。在第 2 部分中&#…

Week2 Using the Java Collection Libraries Lecture 2

1. Java为数据结构编程提供了哪些支持? (1)Java 提供了丰富的数据结构类,通过 Java 集合框架(Java Collections Framework) 来实现,常见的包括: Java 集合框架(Java Col…

武汉大学生命科学学院与谱度众合(武汉)生命科技有限公司举行校企联培座谈会

2025年2月21日下午,武汉大学生命科学学院与谱度众合(武汉)生命科技有限公司(以下简称“谱度众合”)在学院学术厅举行校企联培专业学位研究生合作交流会。武汉大学生命科学学院副院长刘星教授、生命科学学院周宇教授、产…

【随时随地学算法】本地部署hello-algo结合内网穿透远程学习新体验

文章目录 前言1.关于hello-algo2.安装Docker和Docker compose3.本地部署hello-algo4. hello-algo本地访问5.cpolar内网穿透工具安装6.创建远程连接公网地址7.固定Uptime Kuma公网地址 前言 本篇文章主要介绍如何在本地部署hello-algo算法学习必备项目,并结合cpol…

加油站小程序实战教程03站点管理

目录 1 创建数据源2 搭建后台功能2.1 搭建类目配置功能2.2 配置系统信息2.3 配置站点功能2.4 配置油号功能2.5 配置油枪功能2.6 配置站点菜单2.7 设置站点的操作列 总结 在开发小程序的时候,通常需要先拆解业务对应我们的需求分析,根据需求来推导数据结构…

Vidma Ver.2.14.0 高级版

Vidma Ver.2.14.0 高级版 Vidma 是一款易于使用的视频编辑器,提供多种音乐和流行视频效果选择,让您的视频在社交媒体上脱颖而出。您可以通过添加 swooshing 文本、流行效果、复古滤镜、精美贴纸、平滑过渡等等,轻松地从您的宝贵时刻创建有意…

网络通信/IP网络划分/子网掩码的概念和使用

文章目录 概述子网的考题子网掩码的历史有/无类地址子网划分!子网掩码超网技术/CIDR子网掩码和路由IP子网掩码定义 网络规划网络规划-拆子网网络规划-组超网子网划分案例 区分于其他特殊IP地址IP地址和网络地址子网掩码和网络地址子网掩码和广播地址 子网间的通信其他 概述 本…

win11编译pytorch cuda128版本流程

Geforce 50xx系显卡最低支持cuda128,torch cu128 release版本目前还没有释放,所以自己基于2.6.0源码自己编译wheel包。 1. 前置条件 1. 使用visual studio installer 安装visual studio 2022,工作负荷选择【使用c的桌面开发】,安装完成后将…

一周学会Flask3 Python Web开发-Jinja2模版中加载静态文件

锋哥原创的Flask3 Python Web开发 Flask3视频教程: 2025版 Flask3 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 一个Web项目不仅需要HTML模板,还需要许多静态文件,比如 CSS、JavaScript文件、图片以及音频等。在Fla…

DeepSeek开源周 Day04:从DualPipe聊聊大模型分布式训练的并行策略

DualPipe简介 今天是DeepSeek开源周的第四天,官方开源了一种新型并行计算优化策略——DualPipe。 其实大家阅读过Deepseek-V3技术报告的同学,对这个技术并不陌生。 开源地址:https://github.com/deepseek-ai/DualPipe 核心亮点 DualPipe&…

基于C#的CANoe CLR Adapter开发指南

一、引言 CANoe 是一款广泛应用于汽车电子开发和测试的工具,它支持多种编程接口,方便开发者进行自定义扩展。CANoe CLR Adapter 允许我们使用 C# 语言与 CANoe 进行交互,充分利用 C# 的强大功能和丰富的类库。本文将详细介绍如何基于 C# 进行…

Redis实现滑动窗口限流实践(Redisson限流器版)

文章目录 一、滑动窗口限流原理二、Redisson限流器三、代码示例1. 引入依赖2. 配置Redis连接3. 使用Redisson限流器4. 使用示例 四、总结五、其他优化方向六、代码说明 在高并发系统中,为了保护系统稳定性,防止突发流量压垮服务,限流是一种常…

实现Python+Django+Transformers库中的BertTokenizer和BertModel来进行BERT预训练,并将其应用于商品推荐功能

一、环境安装准备 #git拉取 bert-base-chinese 文件#创建 虚拟运行环境python -m venv myicrplatenv#刷新source myicrplatenv/bin/activate#python Django 集成nacospip install nacos-sdk-python#安装 Djangopip3 install Django5.1#安装 pymysql settings.py 里面需要 # 强制…

ollama本地部署DeepSeek-R1大模型使用前端JS调用的详细流程

以下是关于如何在本地部署 DeepSeek-R1 大模型(通过 Ollama),并使用前端 JavaScript 调用其功能的详细流程。 前提条件 硬件要求: 建议至少 16GB RAM(运行较小模型如 1.5B 或 7B 参数版本),如果…

Rocky Linux 8.5 6G内存 静默模式(没图形界面)安装Oracle 19C

Oracle19c 下载地址 Database Software Downloads | Oraclehttps://www.oracle.com/database/technologies/oracle-database-software-downloads.html#db_ee 目录 一、准备服务器 1、服务器可以克隆、自己装 2、修改主机名 3、重启 4、关闭selinux 5、关闭防火墙 5.1、…

【Qt QML】QML鼠标事件(MouseArea)

QML鼠标事件全面解析 一、MouseArea基础概念 在 QML 中,鼠标事件是处理用户与界面元素交互的重要部分。QML 提供了多种方式来处理鼠标事件,MouseArea 是 QML 中用于处理鼠标事件的核心元素,它可以覆盖在其他元素之上,捕获鼠标操作并触发相应的信号。 1、基本用法 import …

【Project】基于Prometheus监控docker平台

一、设计背景 1.1项目简介 本项目旨在创建一个全面的容器化应用程序监控解决方案,基于Prometheus监控Docker平台上的各种服务。在当今的软件开发环境中,容器化技术已成为一种关键的工具,使应用程序能够更快速、可靠地交付和扩展。然而&…

SV——Clocking block的应用

在system verilog中,clocking block是一种简化时钟域信号同步和采样的机制。可以帮助验证工程师简化复杂时序问题,尤其是在测试平台中,既要对信号进行驱动,又要对信号进行采样。 clocking block块一般有以下应用场景:…

RabbitMQ 的介绍与使用

一. 简介 1> 什么是MQ 消息队列(Message Queue,简称MQ),从字面意思上看,本质是个队列,FIFO先入先出,只不过队列中存放的内容是message而已。 其主要用途:不同进程Process/线程T…