当前位置: 首页 > news >正文

常见面试题-TCP三次握手四次挥手

TCP 三次握手/四次挥手

参数用途
SYN用于启动和建立连接时,同步设备之间的序列号。0到2^32 - 1的随机数。
ACK向另一端确认已经收到 SYN,数值为收到 SYN 增一。
SYN-ACK确认之前收到了 SYN,数值为自定义值。
FIN终止连接。
RST重置连接。

三次握手

在这里插入图片描述

三次握手流程为:

  1. 第一次握手:client 请求建立连接,发送 SYN 包到主机 B,并进入 SYN_SEND 状态,等待 server 回应
  2. 第二次握手:server 向 client 发送 SYN+ACK 包,表示也想和 client 建立连接并确认 client 的报文,并进入 SYN_RECV 状态
  3. 第三次握手:client 收到 server 发送的 SYN+ACK 包,向 server 发送 ACK 包

为什么需要三次握手?

有很多种说法,这里列出以下两种说法(自我感觉第一种说法比较浅显易懂):

  • 因为经过了三次握手,主机 A 和主机 B 才可以保证自己的发送能力和接收能力都是正常的,那么理论上双方收发能力正常,证明网络可靠,可以进行通信。
  • 在谢希仁版《计算机网络》中是这样说的,如果 client 发送的第一个 SYN 包并没有丢失,只是在网络中滞留,以致于延误到连接释放以后的某个时间才到达 server。本来这是一个早已失效的报文,但 server 收到此失效报文后,就误认为是 client 再次发出的一个新的连接,于是向 client 发出 SYN+ACK 包,如果不采用三次握手,只要 server 发出 SYN+ACK 包,就建立连接,会导致 client 没有发出建立连接的请求,因此不会理会 server 的 SYN+ACK 包,但是 server 却以为新的连接建立好了,并一直等待 client 发送数据,导致资源被浪费

四次挥手

在这里插入图片描述

四次挥手流程为:

  1. 第一次挥手:客户端想要终止连接时,向服务端发送 FIN,客户端进入 FIN_WAIT_1 状态,表示客户端没有数据要发送给服务端了,但是如果服务端还有数据没有发送完,服务端可以继续发送数据
  2. 第二次挥手:服务端收到客户端终止请求后,回复 ACK 确认 FIN,表示已经收到客户端的中断请求,但是服务端还有数据需要发,此时客户端进入 FIN_WAIT_2 状态,继续等待服务端的 FIN(中断连接) 报文
  3. 第三次挥手:TCP 的连接是相互独立的,当服务端已经发送完数据了,向客户端发送 FIN=1 报文,告诉客户端数据已经发送完毕,准备好关闭连接了,服务端此时进入 LAST_ACK 状态
    • 如果服务端一直没有收到客户端返回的 ACK 报文,那么就会触发超时重传,服务端会重传 FIN 报文
  4. 第四次挥手:客户端收到服务端的 FIN 后,知道可以关闭连接了,因此向服务端发送 ACK 报文,并进入 TIME_WAIT 状态(如果客户端不向服务端发送 ACK ,那么服务端并不请求客户端是否收到了服务端关闭连接的请求,假如服务端发送给客户端的 FIN 报文丢失,那么客户端就一直以为服务端没有请求关闭连接,导致连接无法关闭)
    • 如果客户端在 2msl 内,再次收到了来自服务端的 FIN 报文,说明服务器端没有收到客户端的 ACK 报文,客户端重新向服务端发送 ACK 报文,计时器重置
    • 如果客户端再 2msl 内没有收到服务端的 FIN 报文,说明服务端正常接收了 ACK 确认报文,客户端可以进入 CLOSED 状态

为什么客户端的 TIME_WAIT 时间是 2msl 呢?

首先 msl 是报文的最大生存时间,如果超过 msl,那么报文就会被丢弃

那么客户端等待 2msl 是因为,客户端的 ACK 到达服务端最多花费 1msl,而服务端重发 FIN 报文也最多花费 1msl,因此如果客户端的 ACK 报文丢失,最多 2msl 的时间就可以收到服务端重发的 FIN 报文

为什么要第四次挥手呢?
其实很容易,我们想一下如果没有通过第四次挥手对 server 发给 client 的 FIN 报文进行确认,如果这个报文丢失的话,客户端就不知道需要关闭连接了,服务端也不知道报文丢失,也不重发,导致客户端一直认为连接处于打开状态

相关文章:

  • MySQL 是怎样运行的:单表访问方法及基于成本的优化
  • Windows 同步时间服务器批处理
  • 软件测试常见面试题1000问涵盖一千+公司面试软件测试面试题(全网最全)
  • 安全防御——二、ENSP防火墙实验学习
  • Ecal基于wifi下跨机通讯
  • 服务器的操作系统,你选择哪些?
  • 家政预约服务小程序源码系统 线上+线下两种模式 带完整的搭建教程
  • 运动想象 EEG 信号分析
  • 1.OpenResty系列之入门简介
  • JDBC SQL Server Source Connector: 一览与实践
  • MuLogin浏览器如何在一台设备上安全登录和管理多个LinkedIn账户?
  • 基于人工兔算法的无人机航迹规划-附代码
  • 成功解决fatal error: stdatomic.h: No such file or directory #include <stdatomic.h>
  • kmp算法详解+next数组求解
  • 使用Postman工具做接口测试 —— 环境变量与请求参数格式!
  • 《深入 React 技术栈》
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • Android Volley源码解析
  • Java 内存分配及垃圾回收机制初探
  • Java编程基础24——递归练习
  • Java方法详解
  • JS创建对象模式及其对象原型链探究(一):Object模式
  • Spark RDD学习: aggregate函数
  • weex踩坑之旅第一弹 ~ 搭建具有入口文件的weex脚手架
  • 高程读书笔记 第六章 面向对象程序设计
  • 记录:CentOS7.2配置LNMP环境记录
  • 前端临床手札——文件上传
  • 让你的分享飞起来——极光推出社会化分享组件
  • 什么是Javascript函数节流?
  • 手机端车牌号码键盘的vue组件
  • 原生Ajax
  • ​中南建设2022年半年报“韧”字当头,经营性现金流持续为正​
  • #pragma 指令
  • $().each和$.each的区别
  • ${factoryList }后面有空格不影响
  • $NOIp2018$劝退记
  • (附源码)spring boot网络空间安全实验教学示范中心网站 毕业设计 111454
  • (六)什么是Vite——热更新时vite、webpack做了什么
  • (论文阅读26/100)Weakly-supervised learning with convolutional neural networks
  • (循环依赖问题)学习spring的第九天
  • (轉)JSON.stringify 语法实例讲解
  • .net 7 上传文件踩坑
  • .NET Core日志内容详解,详解不同日志级别的区别和有关日志记录的实用工具和第三方库详解与示例
  • .Net Framework 4.x 程序到底运行在哪个 CLR 版本之上
  • .NET成年了,然后呢?
  • /*在DataTable中更新、删除数据*/
  • @Not - Empty-Null-Blank
  • @RequestMapping 的作用是什么?
  • @四年级家长,这条香港优才计划+华侨生联考捷径,一定要看!
  • [c#基础]DataTable的Select方法
  • [C++]打开新世界的大门之C++入门
  • [CareerCup][Google Interview] 实现一个具有get_min的Queue
  • [CISCN2019 华东北赛区]Web2
  • [CSDN首发]鱿鱼游戏的具体玩法详细介绍