TCP三次握手与四次挥手(TCP重传机制,2MSL)超详细!!!计算机网络

ops/2024/11/28 5:18:12/

本篇是关于3次握手和四次挥手的详细解释~

如果对你有帮助,请点个免费的赞吧,谢谢汪。(点个关注也可以!)

如果以下内容需要补充和修改,请大家在评论区多多交流~。

目录

1. TCP头部:

2. 三次握手

2.1. 3次握手的必要原因:

2.2. 具体步骤:

2.3. 细节:

2.3.1. 第一次握手:

2.3.2. 第二次握手:

2.3.3. 第三次握手:

2.4. 影响TCP三次握手过程的因素:

网络延迟:

丢包率:

网络拥塞:

防火墙和网络安全策略:

系统资源限制:

TCP参数设置:

NAT(网络地址转换)和负载均衡器:

中间网络设备问题:

操作系统和网络栈问题:

应用程序设计:

DoS(拒绝服务)攻击:

3. 4次挥手

3.1. 步骤

3.2. 为什么客户端在TIME-WAIT阶段要等2MSL?

3.2.1. 确保最后的ACK被接收:

3.2.2. 处理网络中延迟的报文:

4. TCP如何保证可靠性传输?

4.1. 通过三次握手建立可靠的连接:

4.1.1. 同步序列号(SYN):

4.1.2. 确认(ACK):

4.2. 通过应答确认和重传机制确认数据准确到达:

4.2.1. 序列号(Seq):

4.2.2. 应答确认(Ack):

4.2.3. 超时重传:

4.2.4. 流量控制:

4.3. 通过四次挥手实现断开连接时信息传输的完整性:

结束(FIN):

确认(ACK):

终止确认:

5. TCP重传机制具体是如何运作的?

5.1. 超时重传(RTO - Retransmission Timeout)

5.2. 快速重传(Fast Retransmit)

5.3. 选择性重传(Selective Repeat)

5.4. 计时器管理

5.5. 流量控制与拥塞控制

5.5.1. 总结


1. TCP头部:

  • Seq(序列号):序列号是TCP头部的一个32位字段,用于标识从发送端发送的数据字节流中的每一个字节。每个TCP段都有一个序列号,用于确保数据能够按照正确的顺序重新组装。对于建立连接的SYN包和结束连接的FIN包,即使它们不携带数据,也会有序列号。
  • Ack(应答号):应答号是TCP头部的一个32位字段,用于指示发送端期望接收的下一个序列号。当发送ACK包时,Ack字段会设置为接收方期望从对方收到的下一个序列号。这表明所有到这个序列号为止的数据都已经成功接收。
  • SYN(同步序列编号):SYN标志是在TCP三次握手中的第一个包中设置的,用于开始一个新的连接。它告诉接收方发送方将开始一个新的序列号,用于后续的数据传输。
  • FIN(结束):FIN标志用于结束一个TCP连接。当一方完成数据发送后,它会发送一个设置了FIN标志的包,以请求关闭连接。
  • PSH(推送):PSH标志指示接收方应该立即将数据推送到应用程序,而不是将其缓存起来。这通常用于需要立即处理的数据,如交互式输入。
  • ACK(确认):ACK标志用于确认包的接收。除了最初的SYN包外,TCP协议要求所有的数据传输包都应该设置ACK标志。

这些标志和字段是TCP协议如何保证可靠传输的关键组成部分。在TCP头部,这些标志可以单独设置,也可以组合设置,以指示不同的控制信息。例如,在三次握手的第二次握手时,服务器会发送一个SYN-ACK包,这个包同时设置了SYN和ACK标志。

2. 三次握手

TCP(传输控制协议)使用三次握手过程来建立可靠的连接

2.1. 3次握手的必要原因:

  1. 同步序列号:客户端和服务器都需要知道对方的初始序列号,以便正确地排序数据段。在三次握手中,双方通过发送和确认序列号来同步这些信息。

  2. 确认双方的接收和发送能力:三次握手确保了双方都有能力发送和接收数据。在第一次握手时,客户端发送一个SYN包,如果服务器能够接收到这个包,那么它就知道客户端的发送能力是正常的。

      在第二次握手时,服务器发送一个SYN-ACK包,客户端如果能够接收到,就知道服务器的发送能力是正常的。

       客户端发送一个ACK包,服务器接收到后,就知道客户端的接收能力也是正常的。

      3. 防止已失效的连接请求突然又传送到了服务端

如果一个旧的连接请求(可能因为网络延迟而长时间滞留)突然到达服务器,通过三次握手可以防止这种情况建立一个错误的连接。因为服务器在接收到SYN后,会发送一个SYN-ACK,如果客户端没有对应的请求(即它没有发送过SYN),它就不会发送ACK,因此连接不会建立。

2.2. 具体步骤:

  • 第一次握手:客户端发送一个SYN包到服务器,以开始一个新的连接。

  • 第二次握手服务器接收到SYN包,会应答一个SYN-ACK包,表示已经收到了客户端的SYN,并准备好建立连接。

  • 第三次握手:客户端收到服务器的SYN-ACK包后,会向服务器发送一个ACK包,确认连接建立。

这个过程确保了双方都准备好数据传输,并且减少了因网络延迟或错误而导致的资源浪费。两次握手不足以完成这些任务,因为它不能防止旧的连接请求干扰新的连接建立。

2.3. 细节:

2.3.1. 第一次握手:

客户端发送一个TCP同步序列编号(SYN)包到服务器,以开始一个新的连接。

在这个SYN包中,序列号(seq)被设置为一个初始值J(通常是随机生成的)。

发送完SYN包后,客户端进入SYN_SENT状态,等待服务器的确认。

2.3.2. 第二次握手:

服务器收到客户端的SYN包后,会发送一个确认包(ACK)回去。

服务器在ACK包中设置确认号(ack)为客户端的序列号J加1,表示收到了序列号为J的SYN包。

同时,服务器也会发送自己的SYN包,其中包含自己的初始序列号K。

服务器此时进入SYN_RECV状态,等待客户端的确认。

2.3.3. 第三次握手:

客户端收到服务器的SYN+ACK包后,会发送一个确认包(ACK)作为响应。

在这个ACK包中,确认号(ack)被设置为服务器的序列号K加1。

发送完这个ACK包后,客户端进入ESTABLISHED状态,表示客户端到服务器的连接已经建立。

服务器在收到这个ACK包后,也进入ESTABLISHED状态,此时双方都准备好开始数据传输。

2.4. 影响TCP三次握手过程的因素:

网络延迟:

网络延迟会影响握手的速度。如果网络延迟较大,那么SYN包和ACK包的往返时间(RTT)会增加,导致建立连接的时间变长。

丢包率:

如果网络中的丢包率较高,SYN或ACK包可能在传输过程中丢失,需要重传,这会延长握手过程。

网络拥塞:

网络拥塞会导致数据包传输延迟或丢失,从而影响握手过程。

防火墙和网络安全策略:

防火墙或其他网络安全设备可能会限制或过滤SYN包,这可能导致握手失败。

系统资源限制:

如果服务器资源有限(如内存不足),它可能无法处理大量的并发握手请求,导致连接建立失败。

TCP参数设置:

诸如TCP窗口大小、SYN重传次数、SYN超时时间等TCP参数的设置也会影响握手过程。

NAT(网络地址转换)和负载均衡器:

NAT设备和负载均衡器可能会改变数据包的流向,影响握手的正常进行。

中间网络设备问题:

路由器、交换机等网络设备如果出现问题,如配置错误或硬件故障,也可能影响握手过程。

操作系统和网络栈问题:

操作系统的网络栈如果有bug或配置不当,可能会影响TCP握手的执行。

应用程序设计:

如果应用程序在建立TCP连接时没有正确处理异常情况,可能会导致握手失败。

DoS(拒绝服务)攻击:

SYN Flood等DoS攻击会发送大量伪造的SYN包,导致服务器资源耗尽,无法处理正常的握手请求。

3. 4次挥手

3.1. 步骤

  1. 第一次挥手

      主动方(可以是客户端或服务器)发送一个FIN包(FIN=1,seq=u),表示它已经完成发送数据,并希望关闭到被动方的连接。

      主动方发送完FIN包后,主动方进入FIN_WAIT_1状态,等待被动方的确认。

  1. 第二次挥手

      被动方收到FIN包后,发送一个ACK包(ACK=1, ack=u+1)作为响应,确认已经收到主动方的终止请求。

      被动方此时进入CLOSE_WAIT状态,这意味着被动方已经知道主动方想要关闭连接,但被动方可能还有数据需要发送。

     主动方收到这个ACK包后,进入FIN_WAIT_2状态,等待被动方发送剩余的数据并关闭连接。

  1. 第三次挥手

      在被动方发送完所有剩余的数据后,它发送一个FIN包(FIN=1, seq=w),请求关闭到主动方的连接。

      发送完FIN包后,被动方进入LAST_ACK状态,等待主动方的最后确认。

  1. 第四次挥手

      主动方收到被动方的FIN包后,发送一个ACK包(ACK=1, ack=w+1)作为响应,确认已经收到被动方的终止请求。

     主动方在发送完ACK包后,进入TIME_WAIT状态,这个状态会持续一段时间(通常是2倍的最大段生命周期MSL),以确保被动方收到最后的ACK包。

     被动方收到这个ACK包后,关闭连接,进入CLOSED状态。

     在TIME_WAIT状态结束后,主动方也会关闭连接,进入CLOSED状态。

     这个过程确保了双方都能优雅地关闭连接,并且所有未完成的数据传输都有机会完成。TIME_WAIT状态的存在是为了防止在网络中延迟的数据包影响后续的连接。

3.2. 为什么客户端在TIME-WAIT阶段要等2MSL?

3.2.1. 确保最后的ACK被接收:

      客户端在发送最后一个ACK确认报文后,不能立即断定服务器端已经收到了这个ACK。如果服务器端没有收到ACK,它可能会重新发送FIN报文。客户端在TIME_WAIT状态中等待2MSL,可以确保如果服务器端的FIN报文因为网络延迟而丢失,服务器端有足够的时间重新发送FIN,并且客户端可以再次发送ACK。

3.2.2. 处理网络中延迟的报文:

        在TCP连接中,可能会存在在网络中长时间延迟的报文。等待2MSL可以确保当前连接中所有延迟的报文都已经过期,从而不会影响后续可能建立的相同源地址和端口号的新连接。

       避免旧连接的报文影响新连接:如果客户端在发送完最后一个ACK后立即关闭连接,并且立即重新建立一个新的连接,那么理论上,网络中延迟的属于旧连接的报文可能会错误地被新连接接收。TIME_WAIT状态防止了这种情况的发生。

      MSL(Maximum Segment Lifetime)是TCP报文在网络中存在的最长时间,这个时间通常是根据网络的特性来设定的。2MSL的等待时间是一个保守的估计,它考虑了报文在网络中的最大存活时间以及往返时间。

     总结来说,客户端在TIME_WAIT状态等待2MSL是为了确保TCP连接的可靠终止,防止因为网络延迟或报文丢失导致的问题,并且保护后续可能建立的连接不受旧连接报文的影响。这也是为什么在TCP四次挥手过程中,客户端比服务器端晚进入CLOSED状态的原因。

4. TCP如何保证可靠性传输?

4.1. 通过三次握手建立可靠的连接:

4.1.1. 同步序列号(SYN):

       三次握手的过程确保了双方都知道对方的初始序列号,这样在后续的数据传输中,双方都可以根据序列号来正确地组装数据。

4.1.2. 确认(ACK):

      在三次握手中,每个方向上的SYN包都会得到一个ACK确认,这确保了连接的双方都准备好接收和发送数据。

4.2. 通过应答确认和重传机制确认数据准确到达:

4.2.1. 序列号(Seq):

        TCP为每个数据字节分配一个序列号,确保数据包在接收端能够按照正确的顺序被重新组装。

4.2.2. 应答确认(Ack):

        接收方收到数据后会发送一个ACK包,其中包含期望收到的下一个序列号。如果发送方没有在预期时间内收到ACK,它会重传数据。

4.2.3. 超时重传:

        如果发送方没有在指定的时间内收到确认,它会认为数据包可能已经丢失或出错,并会重新发送该数据包。

4.2.4. 流量控制:

        TCP使用滑动窗口机制来控制发送方的发送速率,以避免接收方因来不及处理而丢弃数据包。

4.3. 通过四次挥手实现断开连接时信息传输的完整性:

结束(FIN):

        当连接的一端完成数据发送后,它会发送一个FIN包来请求关闭连接。

确认(ACK):

        对端收到FIN包后,会发送一个ACK包作为响应,并进入关闭等待状态,等待剩余的数据传输完成。

终止确认:

        在双方都发送了FIN包并收到了对方的ACK确认后,连接最终会被关闭。这个过程确保了在连接关闭之前,所有的数据都已经传输完成。

        这些机制共同作用,确保了TCP传输的可靠性。通过序列号和确认机制,TCP能够处理数据包的丢失、重复和顺序错误问题,而三次握手和四次挥手过程则确保了连接的建立和终止都是清晰和可靠的。

5. TCP重传机制具体是如何运作的?

        TCP(传输控制协议)的重传机制是网络通信中确保数据可靠传输的关键部分。

5.1. 超时重传(RTO - Retransmission Timeout)

  1. 发送数据:当TCP发送一个数据段时,它会启动一个计时器。

  2. 等待确认(ACK):发送方等待接收方发送确认(ACK)消息。

  3. 计时器到期:如果在计时器到期之前没有收到预期的ACK,发送方认为该数据段可能已经丢失或出错。

  4. 重传数据:计时器到期后,发送方将重传该数据段,并重新启动计时器。

5.2. 快速重传(Fast Retransmit)

快速重传机制是在接收方连续收到三个重复的ACK时触发的,表明接收方期望的下一个数据段丢失了。

  1. 接收重复ACK:如果接收方收到一个已经接收过的数据段,它会发送一个重复的ACK,指示发送方下一个期望的数据序列号。

  2. 连续收到三个重复ACK:当发送方连续收到三个相同的重复ACK时,它会推断出接收方期望的下一个数据段丢失了。

  3. 触发快速重传:发送方立即重传丢失的数据段,而不是等待计时器到期。

5.3. 选择性重传(Selective Repeat)

选择性重传允许发送方只重传丢失的数据段,而不是从丢失的段开始重传所有后续的段。

  1. 接收方指示丢失的段:接收方可以使用SACK(选择性确认)选项来明确告诉发送方哪些数据段丢失了。

  2. 发送方重传丢失的段:发送方根据接收方的指示,只重传丢失的数据段。

5.4. 计时器管理

  • RTO计算:TCP使用各种算法来估算RTO,如Karn算法和Jacobson/Karels算法。这些算法旨在动态调整RTO,以适应网络条件的变化。

  • 退避策略:当数据段被重传时,TCP可能会增加RTO,以避免在网络拥塞时加剧问题。

5.5. 流量控制与拥塞控制

  • 流量控制:TCP使用滑动窗口机制来控制发送方的发送速率,以匹配接收方的处理能力。

  • 拥塞控制:TCP拥塞控制算法(如慢启动、拥塞避免、快速恢复)也会影响重传机制,以避免网络拥塞。

TCP重传机制确保了数据的可靠传输,通过上述机制,TCP能够适应网络延迟、丢包和数据错误的情况,从而提高整体的数据传输效率。当数据段丢失时,TCP会通过超时重传或快速重传来恢复丢失的数据,同时使用选择性重传来优化重传过程。这些机制与流量控制和拥塞控制相结合,使得TCP成为一个非常可靠的传输协议。


http://www.ppmy.cn/ops/137266.html

相关文章

Python中的简单爬虫

文章目录 一. 基于FastAPI之Web站点开发1. 基于FastAPI搭建Web服务器2. Web服务器和浏览器的通讯流程3. 浏览器访问Web服务器的通讯流程4. 加载图片资源代码 二. 基于Web请求的FastAPI通用配置1. 目前Web服务器存在问题2. 基于Web请求的FastAPI通用配置 三. Python爬虫介绍1. 什…

MongoDB相关问题

视频教程 【GeekHour】20分钟掌握MongoDB Complete MongoDB Tutorial by Net Ninja MongoDB开机后调用缓慢的原因及解决方法 问题分析: MongoDB开机后调用缓慢,通常是由于以下原因导致: 索引重建: MongoDB在启动时会重建索引…

Spring集成测试

Spring集成测试是一种用于测试Spring应用程序中各个组件之间的交互和集成的测试方法。它通常用于验证应用程序的整体行为,而不仅仅是单个组件的功能。以下是一些常见的Spring集成测试技术和工具: Spring TestContext Framework: Spring提供了一个强大的测…

【linux】tar命令讲解笔记

Linux tar 命令 Linux tar(英文全拼:tape archive )命令用于备份文件。 tar 是 Linux 和 Unix 系统中用于归档文件和目录的强大命令行工具。 tar 名字来自 "tape archive"(磁带归档),最初用于将…

微信小程序WXSS全局样式与局部样式的使用教程

微信小程序WXSS全局样式与局部样式的使用教程 引言 在微信小程序的开发中,样式的设计与实现是提升用户体验的关键部分。WXSS(WeiXin Style Sheets)作为微信小程序的样式表语言,不仅支持丰富的样式功能,还能通过全局样式与局部样式的灵活运用,帮助开发者构建美观且易于维…

LemoBook - 一个创新性的无数据库网站解决方案!

📢 激动地向大家介绍我最近的开源项目:LemoBook - 一个创新性的无数据库网站解决方案! 🌟 主要特点: 零数据库依赖:完全基于 GitHub 进行内容存储和版本控制现代技术栈:Next.js 14 Tailwind …

鸢尾花Iris训练数据和测试数据的分割和训练数据的散点图矩阵绘制

鸢尾花Iris训练数据和测试数据的分割和训练数据的散点图矩阵绘制 鸢尾花Iris训练数据和测试数据的分割和训练数据的散点图矩阵绘制 鸢尾花Iris训练数据和测试数据的分割和训练数据的散点图矩阵绘制一、训练数据和测试数据1.1 训练数据(training data)1.2…

error Unexpected ‘debugger‘ statement no-debugger

[eslint] D:\System File\Desktop\后台\test\test\src\components\HelloWorld.vue 19:5 error Unexpected debugger statement no-debugger ✖ 1 problem (1 error, 0 warnings) You may use special comments to disable some warnings. Use // eslint-disable-next-li…