计算机网络:三次握手和四次挥手详解

news/2024/12/22 16:20:29/

三次握手和四次挥手

三次握手

概念

为什么需要握手:握手的作用就是为了同步一些信息,比如最大滑动窗口

TCP:是一个可靠的连接,也就是客户端和服务器双方必须感知对方的存在,也就是需要经历一个建立连接的过程

用三次握手建立TCP连接,连接有三个阶段

  • 建立连接
  • 数据传输
  • 连接释放

连接的管理就是使连接的建立和释放都能正常地进行,连接阶段过程中要解决以下三个问题

  • 要使每一方都能确知对方的存在
  • 要允许双方协商一些参数
  • 能够对运输实体分配资源

TCP连接建立过程

TCP建立连接的过程:被称为握手

① 握手过程其实是发送的TCP报文,在这里面有两个字段,SYN 和 seq

  • SYN = 1:表示该报文不能携带数据,但是需要消耗一个SEQ(序号),可以想象成我们对消息编号
  • seq:TCP的每个字节发送的时候,都有一个序号,主要是为了保证可靠性,比如当我服务器通过TCP报文得到了有N个字节需要接受,但是最后只接受到了N-1个,我们通过序号就知道哪个没有被接收到。
  • 客户端进入SYN_SENT状态,即同步已发送

② 当服务器接受到我们的握手请求时,会回复一个确认报文

  • SYN:表示不携带数据,同时消耗一个SEQ = y(这里的y是任意数字,可以是1,2,3,4)
  • ACK:=1 表示这是一条确定报文
  • ack:x+1,其中x是刚刚客户端发送过来的
  • 服务器进入SYN_RECVD状态,即同步已收到

③ 当客户端收到确认报文的时候,客户端需要对这个确认报文进行回复

  • ACK:=1,表示这是一条确认报文
  • seq:= x +1,
  • ack:= y+1

经过了这三次握手,两者就进入了连接状态

通俗理解

  • 客户端:服务器,我们可以建立连接么? -> SYN= 1 , seq = x
  • 服务器:可以啊,我们建立连接吧 ! -> ACK =1, SYN = 1, seq = y, ack = x+1
  • 客户端:收到,建立连接吧! -> ACK = 1, SYN = 1,seq = x + 1, ack = y + 1

然后建立TCP连接

为什么是三次握手

假如四次握手

四次连接有点多余,第三次的时候,我们已经互相进行了连接确认

但是因为我们无法保证百分百的可靠性

假如两次握手:

客户端知道服务器有接收 和 发送的能力,服务器不知道客户端有没有接收数据的能力,因为通过第一次握手,已经知道了客户端能够发送数据,但是能不能接收数据,还是不清楚,因此这个TCP连接是不可靠的。

为什么不能两次握手就建立连接

因为超时重传机制的存在

但客户端发送第一次握手的时候,可能会经历网络拥塞,然后客户端会以为这个连接已经丢失,然后会重新发送一个请求连接的信息到服务器,这次发送的消息很快被服务器接受,然后服务器建立连接就开始建立连接。但是当第一次发送的请求经过一段时间的阻塞后,成功到达服务器,然后服务器又连接连接,而此时客户端是不会理会这次请求的建立,所以服务器一直在等待客户端数据的发送。

四次挥手

所谓的四次挥手,就是关闭TCP连接的过程,指的是断开一个TPC连接,需要客户端和服务端总共发送4个包,以确定双方连接的断开。

主要目的:保证TCP连接的全双工连接

由于TCP连接是全双工的,因此每个方向都必须单独关闭,这个原则是当以防完成它的数据发送任务后,就能发送一个FIN包来终止这个方向的连接。

收到一个FIN包只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后,仍然能发送数据,首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。

四次挥手过程

  • 第一次挥手:客户端发送一个FIN包(FIN=1,seq=U)给服务器,用来关闭客户端到服务器端的数据传输,客户端进入FIN_WAIT_1状态(终止等待)
  • 第二次挥手:服务器端收到FIN包后,发送一个ACK包(ACK=1,ack=u+1,在随机产生一个值v 给seq)给客户端,服务器进入了CLOSE_WAIT状态(关闭等待)
  • 第三次挥手:服务器端发送一个FIN包(FIN=1,ACK=1,ack=u+1,在随机产生 一个w值给seq)给客户端,用来关闭服务器到客户端的数据传输,服务端进入了LAST_ACK(最后确定)状态
  • 第四次挥手:客户端接收FIN包,然后进入TIME_WAIT状态,接着发送一个ACK包(ACK=1,seq=u+1, ack = w+1) 给服务端,服务端确定序号,进入CLOSe状态,完成了四次挥手。

挥手中的状态

  • CLOSED:表示初始状态
  • ESTABLISHED:表示连接已经连接
  • FIN_WAIT:状态FIN_WAIT_1和FIN_WAIT_2都表示等待对方的FIN报文,这两个状态的区别是,当主动发送方给对方发送了断开请求时,就进入了FIN_WAIT_1状态,而到被动方在回应后,主动发送方就进入了FIN_WAIT_2。
  • FIN_WAIT_2:上面已经详细解释了这种状态,实际上FIN_WAIT_2状态下的SOCKET,表示半连接,也即有一方要求close连接,但另外还告诉对方,我暂时还有点数据需要传送给你,稍后再关闭连接
  • CLOSE_WAIT:这个状态的含义是 表示在等待关闭
  • LAST_ACK:在被动关闭放发送FIN报文后,最后等待对方的ACK报文,当收到了ACK报文后,就进入了CLOSE状态。

为什么TIME_WAIT状态还需要等待2MSL后才能返回CLOSE

这是因为虽然双方都同意了关闭连接,而且握手的4个报文也都协调和发送完毕,按道理可以直接回到CLOSE状态

但是因为我们需要假设网络是不可靠的,你无法保证你最后发送的ACK报文是会一定被对方收到,因此处于LAST_ACK状态下的socket可能会因为超时未收到ACK报文,而重发FIN报文,所以这个TIME_WAIT状态的作用就是用来重发可能丢失的报文。


http://www.ppmy.cn/news/1533248.html

相关文章

【Verilog学习日常】—牛客网刷题—Verilog企业真题—VL63

并串转换 描述 题目描述: 设计一个模块进行并串转换,要求每四位d输为转到一位dout输出,输出valid_in表示此时的输入有效。 信号示意图: clk为时钟 rst为低电平复位 valid_in 表示输入有效 d 信号输入 dout 信号输出 …

SQL_over_partition_by_order_by

在SQL中,OVER子句通常与窗口函数一起使用,用于定义窗口的规则。PARTITION BY用于将数据分成多个独立的分区,而ORDER BY用于在每个分区内定义数据的排序方式。 窗口函数可以对一组行执行计算,并返回计算结果。这些行与当前行有某种…

【07】纯血鸿蒙HarmonyOS NEXT星河版开发0基础学习笔记-Swiper轮播组件与样式结构重用

序言: 本文详细讲解了关于我们在页面上经常看到的轮播图在鸿蒙开发中如何用Swiper实现,介绍了Swiper的基本用法与属性,及如何面对大段的重复代码进行封装和重用(Extend、Styles、Builder),使代码更加简洁易…

【四】Spring Cloud OpenFeign原理分析

Spring Cloud OpenFeign原理分析 概述 Spring Cloud 微服务实践也有挺多年了,一直想着总结一下这系列的知识点,最近终于下定决心来出一个Spring Cloud 系列文章了。本文主要围绕fegin组件来进行讲解,文中将会给出基础使用的示例,还…

(Linux驱动学习 - 4).Linux 下 DHT11 温湿度传感器驱动编写

DHT11的通信协议是单总线协议,可以用之前学习的pinctl和gpio子系统完成某IO引脚上数据的读与写。 一.在设备树下添加dht11的设备结点 1.流程图 2.设备树代码 (1).在设备树的 iomuxc结点下添加 pinctl_dht11 (2).在根…

如何选用笔记本进行思路整理

用螺纹圈装订的口袋大小的无格白纸/点状硬皮笔记本有许多优点,适合多种用途,尤其在学习和思路整理方面。 ### 优点 1. **便携性**:口袋大小的设计方便随身携带,适合在任何地方记录灵感。 2. **灵活性**:无格白纸提供…

SpringBoot+Activiti7工作流入门实例

目录 文章目录 目录准备Activiti建模工具1、BPMN-js在线设计器1.1 安装1.2 使用说明1.3运行截图2、IDEA安装Activiti Designer插件2.1安装插件2.2 设置编码格式防止中文乱码2.3 截图简单工作流入门实例1. 新建Spring Boot工程2. 引入Activiti相关依赖添加版本属性指定仓库添加依…

使用yum为centos系统安装软件以及使用(包含阿里云yum源配置)

centos系统配置阿里云yum源 因为centos7官方停止维护,自带yum源用不了了,所以可以更换成阿里云yum源 方法: 使用root权限执行以下语句 curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo CentOS…