【杂记-TCP协议三次握手、四次挥手始末详解】

2024-05-28 18:20

本文主要是介绍【杂记-TCP协议三次握手、四次挥手始末详解】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、三次握手前:

使用TCP协议的原因
TCP协议的目的是为了保证数据能在两端准确、连续的传输。
传输中使用Socket数据结构
TCP协议可使一个设备能同时与多个设备交互信息,它必须要保证不同传输通道之间不会产生串联或相互影响,所以TCP使用Socket数据结构来实现不同设备之间的连接。
Socket包含两个成分:IP地址和端口号,一个设备可以对应一个IP,其中不同的传输通道用不同的端口号区分开来,于是同一个设备发送给其他不同设备的信息就不会产生混乱。
传输控制块TCB的作用
设备可能会产生多种数据并分发给不同的设备,为了确保数据能够正确分发:TCP使用TCB,也叫传输控制块的数据结构把发给不同设备的数据封装起来,该结构看做是信封。
TCB数据块包含数据发送双方的Socket信息,以及装载数据的缓冲区。在两个设备要建立连接和发送数据之前,双方会分配内存建立起TCB数据块。
TCB的打开方式及其状态
无论是客户端还是服务端,在建立连接前都需要准备好TCB数据结构。
客户端TCB主动打开:客户端主动向服务器表达自己想建立数据连接的请求,此时TCB状态为:Active Open(Create TCB)。
服务端TCB被动打开:由于服务器不知道有哪个设备想向它发起连接,因此在构建TCB模块时会默认将客户端对应的Socket数据初始化为0,服务器保持监听,等待客户端从该端口向它发起连接请求,此时TCB状态为:Passive Open(Create TCB)。
双方把自己的Socket和TCB数据结构准备好后,就可以进入三次握手的过程。

二、三次握手过程:

TCP协议终端两种数据包
一种数据包用来传输数据;一种数据包用来发送控制信息(SYN、ACK等),TCP报头中的标志位用于表明数据包是用于数据发送还是用于传输控制信息。
SYN:Synchronize,同步。
ACK:Acknowledge,确认。
TCP报头的标志位
当标志位中的SYN比特位启动时,表明当前数据包目的是实现双方数据状态同步。
当标志位中的ACK比特为启动时,表明数据包用于通知接收方已收到了数据。
一是客户端通知服务器,“我想建立连接”。二是双方通知对方自己数据发送时的“初始序列号”。三是实现参数交换,把自己的有关信息发送给对方。
简述三次握手的过程
TCP三次握手只是建立连接的过程,和后续的数据传输关系不大。
1、两端未建立连接时,均处于初始状态CLOSED。
2、客户端给服务端发送带有初始序列号ISN的SYN数据包,由CLOSED状态进入到SYN_SENT状态。
3、服务端Socket处于监听状态LISTEN,当收到来自客户端的数据包后,会将客户端的ISN的值加1作为ACK包,并和SYN包一起回发给客户端,由LISTEN状态进入到SYN_RCVD状态。
4、客户端收到来自服务端的数据包后,会将客户端的ISN的值加1作为ACK包,并发送给服务端,由SYN_SENT状态进入到ESTABLISH状态。
5、服务端收到来自客户端的ACK数据包后,由SYN_RCVD状态进入到ESTABLISH状态。
6、至此连接连接建立成功,双方互相发送数据。
初始序列号是随机数
为了防止由于网络波动等原因,先后接收到同一序列号导致握手异常,所以初始序列号是一个随机数,而不是每次都以1开始。
另外,三次握手是实现客户端和服务端交互ISN,以便让对方知道如何按序列号组装数据,如果ISN是固定的,攻击者很容易猜出后续的确认号。

三、其他要点

半连接状态(队列)
服务器第一次收到客户端的SYN时(或服务端给客户端回SYN+ACK包时),处于SYN_RCVD状态,此时双方并没有建立连接,服务器会将这种状态下的请求放在一个队列中, 将这种队列称之为半连接队列,全连接队列就是完成三次握手之后,建立的连接就会放在全连接队列中,如果队列满了就有可能出现丢包的现象。
SYN-ACK重传
服务器发送完SYN-ACK包,如果没有收到客户端的ACK确认包,服务器进行首次重传,等待一段时间还没有收到客户端确认包,会进行第二次重传,如果重传次数超过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除。
关于数据包的大小
在TCP数据传输过程中往往需要通过控制数据包调整各种控制参数,在三次握手过程中,需要传输的控制参数为最大分片大小,也就是数据包中一次能发送的最大字节数,当要发送的数据大于该参数时,数据就必须分成若干小块分别发送。
握手为什么是三次?
第一次握手,服务端收到客户端发送的数据包,服务端可以得到结论:客户端的发送能力、服务端的接收能力正常。
第二次握手,客户端收到了服务端发送的数据包,客户端得到结论:服务端的接收与发送能力、客户端的接收与发送能力是正常的。
但是,此时服务端不能确认客户端的接收能力是否正常,就需要第三次握手。
即,最少需要三次握手的真正原因是:客户端和服务端都能得到“自己和对方的接收与发送能力均正常”的结论。
握手过程可携带数据吗?
第一次、第二次握手不可以携带数据,其原因是防止服务器受到攻击,服务器不用花费太多时间去处理第一次和第二次,而第三次的时候,客户端已经处于Establish状态,且知道了服务器的接收发送能力正常,所以可以携带数据。

四、四次挥手过程

报文发送过程和两端状态
1、客户端申请断开连接,发送FIN报文(报文中会指定一个序列号)给服务端,客户端由Establish状态进入到FIN_WAIT1状态。
2、服务端收到FIN报文,发送ACK报文(把客户端的序列号值+1作为ACK报文)给客户端,服务端由Establish状态进入到CLOSED_WAIT状态,客户端由FIN_WAIT1状态进入到FIN_WAIT2状态。
3、服务端发送FIN报文(指定一个序列号)给客户端,服务端由CLOSED_WAIT状态进入到LAST_ACK状态。
4、客户端收到FIN报文,发送ACK报文(把服务端的序列号值+1作为ACK报文)给服务端,客户端由FIN_WAIT2状态进入到TIME_WAIT状态。
5、服务端收到ACK报文,由LAST_ACK状态进入到CLOSED状态。
6、客户端在2MSL计时时间后,由TIME_WAIT状态进入到CLOSED状态。
为什么客户端要进入TIME_WAIT状态
客户端发送了ACK之后不会直接到CLOSED状态,需原因就是要确保服务器是否已经收到了ACK报文,如果没有收到的话,服务器会重新发送FIN报文给客户端,客户端再次收到ACK报文之后,就知道之前的ACK丢失了,然后再次发送ACK报文。
而TIME_WAIT持续时间至少是一个报文的来回时间,也就是2MSL,计时时间内没有再次收到FIN报文,就代表对方成功接收ACK报文,此时才会处于CLOSED状态。

这篇关于【杂记-TCP协议三次握手、四次挥手始末详解】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1011328

相关文章

Linux换行符的使用方法详解

《Linux换行符的使用方法详解》本文介绍了Linux中常用的换行符LF及其在文件中的表示,展示了如何使用sed命令替换换行符,并列举了与换行符处理相关的Linux命令,通过代码讲解的非常详细,需要的... 目录简介检测文件中的换行符使用 cat -A 查看换行符使用 od -c 检查字符换行符格式转换将

详解C#如何提取PDF文档中的图片

《详解C#如何提取PDF文档中的图片》提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使用,下面我们就来看看如何使用C#通过代码从PDF文档中提取图片吧... 当 PDF 文件中包含有价值的图片,如艺术画作、设计素材、报告图表等,提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使

Android中Dialog的使用详解

《Android中Dialog的使用详解》Dialog(对话框)是Android中常用的UI组件,用于临时显示重要信息或获取用户输入,本文给大家介绍Android中Dialog的使用,感兴趣的朋友一起... 目录android中Dialog的使用详解1. 基本Dialog类型1.1 AlertDialog(

C#数据结构之字符串(string)详解

《C#数据结构之字符串(string)详解》:本文主要介绍C#数据结构之字符串(string),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录转义字符序列字符串的创建字符串的声明null字符串与空字符串重复单字符字符串的构造字符串的属性和常用方法属性常用方法总结摘

Java中StopWatch的使用示例详解

《Java中StopWatch的使用示例详解》stopWatch是org.springframework.util包下的一个工具类,使用它可直观的输出代码执行耗时,以及执行时间百分比,这篇文章主要介绍... 目录stopWatch 是org.springframework.util 包下的一个工具类,使用它

Java进行文件格式校验的方案详解

《Java进行文件格式校验的方案详解》这篇文章主要为大家详细介绍了Java中进行文件格式校验的相关方案,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、背景异常现象原因排查用户的无心之过二、解决方案Magandroidic Number判断主流检测库对比Tika的使用区分zip

Java实现时间与字符串互相转换详解

《Java实现时间与字符串互相转换详解》这篇文章主要为大家详细介绍了Java中实现时间与字符串互相转换的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、日期格式化为字符串(一)使用预定义格式(二)自定义格式二、字符串解析为日期(一)解析ISO格式字符串(二)解析自定义

springboot security快速使用示例详解

《springbootsecurity快速使用示例详解》:本文主要介绍springbootsecurity快速使用示例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录创www.chinasem.cn建spring boot项目生成脚手架配置依赖接口示例代码项目结构启用s

Python中随机休眠技术原理与应用详解

《Python中随机休眠技术原理与应用详解》在编程中,让程序暂停执行特定时间是常见需求,当需要引入不确定性时,随机休眠就成为关键技巧,下面我们就来看看Python中随机休眠技术的具体实现与应用吧... 目录引言一、实现原理与基础方法1.1 核心函数解析1.2 基础实现模板1.3 整数版实现二、典型应用场景2

一文详解SpringBoot响应压缩功能的配置与优化

《一文详解SpringBoot响应压缩功能的配置与优化》SpringBoot的响应压缩功能基于智能协商机制,需同时满足很多条件,本文主要为大家详细介绍了SpringBoot响应压缩功能的配置与优化,需... 目录一、核心工作机制1.1 自动协商触发条件1.2 压缩处理流程二、配置方案详解2.1 基础YAML