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

TCP协议的三次握手和四次挥手(面试)

三次握手

首先可以简单的回答:

      1、第一次握手:客户端给服务器发送一个 SYN 报文。

      2、第二次握手:服务器收到 SYN 报文之后,会应答一个 SYN+ACK 报文。

      3、第三次握手:客户端收到 SYN+ACK 报文之后,会回应一个 ACK 报文。

      4、服务器收到 ACK 报文之后,三次握手建立完成。 

也可以详细的介绍:

刚开始客户端处于 closed 的状态,服务端处于 listen 状态。然后
      1、第一次握手:客户端给服务端发一个 SYN 报文,并指明客户端的初始化序列号 ISN(c)。此时客户端处于 SYN_Send 状态。

      2、第二次握手:服务器收到客户端的 SYN 报文之后,会以自己的 SYN 报文作为应答,并且也是指定了自己的初始化序列号 ISN(s),同时会把客户端的 ISN + 1 作为 ACK 的值,表示自己已经收到了客户端的 SYN,此时服务器处于 SYN_REVD 的状态。

      3、第三次握手:客户端收到 SYN 报文之后,会发送一个 ACK 报文,当然,也是一样把服务器的 ISN + 1 作为 ACK 的值,表示已经收到了服务端的 SYN 报文,此时客户端处于 establised 状态。

      4、服务器收到 ACK 报文之后,也处于 establised 状态,此时,双方以建立起了链接。

为什么只有三次握手才能确认双方的接受与发送能力是否正常

 这里先解释一下为啥只有三次握手才能确认双方的接受与发送能力是否正常,而两次却不可以:
          第一次握手:客户端发送网络包,服务端收到了。这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。
          第二次握手:服务端发包,客户端收到了。这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。
          第三次握手:客户端发包,服务端收到了。这样服务端就能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。

      因此,需要三次握手才能确认双方的接收与发送能力是否正常。

三次握手的作用:

三次握手的作用也是有好多的,多记住几个,保证不亏。例如:
      1、确认双方的接受能力、发送能力是否正常。
      2、指定自己的初始化序列号,为后面的可靠传送做准备。
      3、如果是 https 协议的话,三次握手这个过程,还会进行数字证书的验证以及加密密钥的生成到。

为什么要进行三次握手?

当进行第一次握手,网络不好可能会堵塞,所以连接的请求并没有到达服务器端;
但是tcp连接有超时重传的机制,所以再一次发送请求,这时候服务器端接收到了你的请求,他也会返回一个请求给你,这是第二次握手;
但是这时候网络环境突然又好了起来,那个堵塞的请求到达了服务器端,服务器端又给你回了一个请求,但是你又不想给服务器发送请求,这时候服务器的资源会进行占用等待你的请求,为了不使服务器的资源继续占用,你又必须发送一个请求给服务器;
所以要进行3次握手

下面进行四次挥手介绍:

        当应用程序希望通过 TCP 与另一个应用程序通信时,它会发送一个通信请求。这个请求必须被送 到一个确切的地址。在双方“握手”之后,TCP 将在两个应用程序之间建立一个全双工 (full-duplex) 的通信。   

        这个全双工的通信将占用两个计算机之间的通信线路,直到它被一方或双方关闭为止。

 

1、第一次挥手:客户端发送一个 FIN 报文,报文中会指定一个序列号。此时客户端处于FIN_WAIT1状态。

2、第二次握手:服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序列号值 + 1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了,此时服务端处于 CLOSE_WAIT状态。

3、第三次挥手:如果服务端也想断开连接了,和客户端的第一次挥手一样,发给 FIN 报文,且指定一个序列号。此时服务端处于 LAST_ACK 的状态。

4、第四次挥手:客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 + 1 作为自己 ACK 报文的序列号值,此时客户端处于 TIME_WAIT 状态。需要过一阵子以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态

5、服务端收到 ACK 报文之后,就处于关闭连接了,处于 CLOSED 状态。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【ARMv8/v9 GIC- 700 系列 1 -- Programmers model for GIC-700】
  • 除自身以外数组的乘积_前缀和
  • 思腾合力邀您共赴第十一届医学图像计算青年研讨会(MICS 2024)
  • 嵌入式Qt开发C++核心编程知识万字总结
  • 下载安装JavaFX及解决报错:缺少 JavaFX 运行时组件, 需要使用该组件来运行此应用程序|Eclipse
  • 【Vue】vue-element-admin组件化功能
  • 开始性能测试之前的准备工作!
  • 金龙鱼:只是躺枪?
  • 焊盘的制作
  • STM32-外部中断浅析
  • Android Settings应用 PreferenceScreen 条目隐藏实现和简单分析
  • 102.qt qml-最全Table交互之多列固定、行列拖拽、自定义委托、标题交互使用教程
  • PostGIS2.4服务器编译安装
  • 宝塔面板运行Admin.net框架
  • linux ssh 远程执行shell 获取返回值
  • Angular 响应式表单之下拉框
  • Django 博客开发教程 16 - 统计文章阅读量
  • Javascript 原型链
  • Laravel Mix运行时关于es2015报错解决方案
  • Linux各目录及每个目录的详细介绍
  • mysql 数据库四种事务隔离级别
  • Python十分钟制作属于你自己的个性logo
  • Webpack入门之遇到的那些坑,系列示例Demo
  • 从setTimeout-setInterval看JS线程
  • 仿天猫超市收藏抛物线动画工具库
  • 前端自动化解决方案
  • 如何优雅地使用 Sublime Text
  • 数据科学 第 3 章 11 字符串处理
  • 通过获取异步加载JS文件进度实现一个canvas环形loading图
  • 我有几个粽子,和一个故事
  • 在Unity中实现一个简单的消息管理器
  • 资深实践篇 | 基于Kubernetes 1.61的Kubernetes Scheduler 调度详解 ...
  • $.ajax,axios,fetch三种ajax请求的区别
  • $.proxy和$.extend
  • (2.2w字)前端单元测试之Jest详解篇
  • (24)(24.1) FPV和仿真的机载OSD(三)
  • (C#)Windows Shell 外壳编程系列9 - QueryInfo 扩展提示
  • (搬运以学习)flask 上下文的实现
  • (超简单)使用vuepress搭建自己的博客并部署到github pages上
  • (附源码)spring boot车辆管理系统 毕业设计 031034
  • (论文阅读22/100)Learning a Deep Compact Image Representation for Visual Tracking
  • (免费分享)基于springboot,vue疗养中心管理系统
  • (三十五)大数据实战——Superset可视化平台搭建
  • (转)VC++中ondraw在什么时候调用的
  • (总结)Linux下的暴力密码在线破解工具Hydra详解
  • .bat批处理(十):从路径字符串中截取盘符、文件名、后缀名等信息
  • .net core使用EPPlus设置Excel的页眉和页脚
  • .sh文件怎么运行_创建优化的Go镜像文件以及踩过的坑
  • [2018][note]用于超快偏振开关和动态光束分裂的all-optical有源THz超表——
  • [Angular 基础] - 数据绑定(databinding)
  • [Angular] 笔记 20:NgContent
  • [bug总结]: Feign调用GET请求找不到请求体实体类
  • [C++]四种方式求解最大子序列求和问题
  • [CISCN 2023 初赛]go_session
  • [codeforces]Levko and Permutation