首页 > 其他分享 >详解TCP协议

详解TCP协议

时间:2025-01-21 12:02:03浏览次数:3  
标签:协议 ACK 报文 TCP 发送 详解 接收 客户端

TCP协议全称为传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议。与UDP协议最大的不同是,其会保证消息传输的可靠性。

TCP协议格式

源端口:标识发送进程。

目的端口:标识目的进程

32位序号:标识从 TCP 发送端向 TCP 接收端发送的数据字节流,表示报文段中的第一个数据字节的序号。

32位确认序号:接收端表示接收方期望收到的下一个字节的序列号,该序号前的数据均已被接收。

4位首部长度:TCP 头部的长度,因为 TCP 头部的长度是可变的(20 字节到 60 字节)。

保留字段:这部分目前还没有被使用,通常设置为 0,用于未来可能的协议扩展。

控制位:共有 6 位,分别是 URG、ACK、PSH、RST、SYN 和 FIN:

  • URG:当 URG = 1 时,表示紧急指针字段有效,用于发送紧急数据。
  • ACK:ACK = 1 时,表示确认号字段有效。
  • PSH:PSH = 1 时,接收方在收到数据后应该尽快将数据交给应用程序,而不是等待缓冲区满。
  • RST:RST = 1 时,表示重置连接。当出现错误情况,如连接异常中断或者收到无效的数据包时,会发送带有 RST 位的数据包来重置连接。
  • SYN:用于建立连接。在 TCP 三次握手过程中,第一次握手时,客户端发送的数据包中 SYN = 1,第二次握手时,服务器返回的数据包中 SYN = 1 且 ACK = 1,第三次握手时,客户端发送的数据包中 ACK = 1。。
  • FIN:用于释放连接。当一方完成数据发送,想要关闭连接时,会发送带有 FIN = 1 的数据包。

窗口大小:16 位长。它用于流量控制,指示接收方还能够接收的字节数。

校验和:报文是否在传输过程中出现错误。发送方会计算头部和数据的校验和并填充,接收方会重新计算校验和并与收到的校验和进行比较。如果两者不相等,就表示数据在传输过程中出现了错误,需要进行重传等操作。

紧急指针:当 URG 位被设置为 1 时,紧急指针指向紧急数据的末尾位置。这可以让接收方优先处理紧急数据。

选项:选项字段是可变长度的,用于提供额外的功能,如最大段大小(MSS)协商等。填充字段是为了保证 TCP 头部长度是 32 位的整数倍。

确认应答机制

为了保证消息传输的可靠性,发送方需要知道接收方又没有收到消息,收到了多少字节,为此TCP引入了确认应答机制。

TCP协议中发送的每个字节都有编号即序列号,发送方发送数据时,会在 TCP 段的首部中携带该段数据的起始序列号。即第一个字节的序列号。

接收方收到 TCP 段后,会按序号将它们重新组装成完整的数据流。当接收方接收并处理完一段数据后,会向发送方发送一个确认(ACK)报文段,其中ACK位设为1,同时写入32位确认序号,表示该序列号之前的所有数据都已正确接收。

在以下几种情况下会发送确认报文:

正常接收数据后

  • 按序接收:当接收方按顺序正确接收到发送方发送的 TCP 报文段中的数据时,会立即发送确认报文。

  • 乱序接收:如果接收方收到的报文段中的数据不是按顺序到达的,接收方会先将其放入接收缓冲区进行排序。当接收方成功将乱序的数据重新排序并确认所有数据都已完整接收后,会发送确认报文,确认序号为期望接收的下一个序列号。

接收方有接收能力时

  • 接收窗口更新:接收方的接收窗口大小会随着接收缓冲区的使用情况而动态变化。当接收方的接收窗口大小发生变化,且有更多的空间可以接收数据时,接收方会发送确认报文,在确认报文中告知发送方新的接收窗口大小。

特定事件发生时

  • 零窗口探测响应:当发送方收到接收方的零窗口通知后,会启动持续计时器,在计时器到期后发送一个零窗口探测报文段。接收方在收到该探测报文段时,会回复当前的窗口大小,这个回复的报文也是一种确认报文,告知发送方当前的接收窗口状态3。
  • 重复确认:如果接收方发现有数据包丢失,会发送重复的确认消息,即连续发送多个相同确认序号的确认报文。当发送方连续收到 3 个或以上的重复 ACK 时,就会立即重传丢失的数据包1。

超时重传机制 

对于TCP,只有确认应答还不够,在消息丢失后还要有相应的弥补措施。

当发送方发送一个 TCP 数据包时,会同时启动一个重传定时器。相当于一个定时闹钟,时间是根据往返时间(RTT)估算出来的。

如果定时器超时,发送方还没有收到确认消息,就认为数据包可能丢失了或者确认消息丢失了。此时,发送方会重新发送这个数据包,并重新启动定时器,等待接收方的确认。

对于具体细节可以参考这篇博客:

TCP/IP协议栈:TCP超时重传机制_如果出现二义性直接不作处理,所以直接将rtt的值设置为两倍-CSDN博客

快速重传机制

在 TCP 中,超时重传机制需要等待定时器超时才会重传丢失的数据包。等待时间较长,会影响传输效率。为了提高效率,TCP引入了快速重传机制,可以更快地检测和重传丢失的数据包,减少等待时间,提高 TCP 传输的性能。

接收方在收到数据包时,会发送确认报文,其确认号是期望收到的下一个序列号,即丢失报文的初始序列号。因为在丢失报文之前的数据均被接送。

如果接收方连续收到多个相同确认号的 ACK 报文,就表明某个数据包可能丢失了。接收方会重传数据包。

三次握手

与UDP不同,TCP在进行通信时会先建立连接。这个连接建立的过程被称为 “三次握手”。

第一次握手: 

客户端向服务器发送一个设置了 SYN 标志位的 TCP 报文,该报文同时包含客户端随机生成的初始序列号,假设为 x。此时,客户端进入 SYN_SENT 状态,等待服务器的响应。

第二次握手:

服务器接收到客户端的 SYN 报文段后,会向客户端发送一个包含 SYN 和 ACK 标志位的 TCP 报文。SYN 标志位用于同步序列号,服务器也会随机生成一个初始序列号,假设为 y。

ACK 标志位用于确认客户端的连接请求,确认序号为客户端的序列号 x 加 1,即 ack = x + 1。此时,服务器进入 SYN_RCVD 状态。

第三次握手:

客户端接收到服务器的 SYN + ACK 报文段后,会向服务器发送一个包含 ACK 标志位的 TCP 报文段。确认号为服务器的序列号 y 加 1,即 ack = y + 1,而序列号为客户端在第一次握手中发送的序列号 x 加 1,即 seq = x + 1。

服务器收到这个 ACK 报文段后,连接建立成功,双方进入 ESTABLISHED 状态,开始进行数据传输。

四次挥手

四次挥手是 TCP 协议中用于断开连接的过程:

第一次挥手:

客户端调用 close 函数关闭套接字,客户端向服务器发送一个  FIN 标志位被置为 1 的 TCP 报文,该报文包含客户端想要关闭连接的请求,此时客户端进入 FIN_WAIT_1 状态,表示客户端已经没有数据要发送给服务器了,但还可以接收服务器的数据。

第二次挥手:

服务器接收到客户端发送的 FIN 报文后,会发送一个 ACK标志位被置为 1 的 TCP 报文段作为应答,确认序号为收到的 FIN 报文段的序号加 1。服务器进入 CLOSE_WAIT 状态,此时连接处于半关闭状态,即客户端不再发送数据,但服务器还可以继续向客户端发送数据。客户端收到服务器的 ACK 报文段后,进入 FIN_WAIT_2 状态。

第三次挥手:

服务端调用 close 函数关闭套接字发送 FIN 报文,请求关闭连接,此时服务器进入 LAST_ACK 状态

第四次挥手:

客户端收到服务器发送的 FIN 报文段后,会发送 ACK 报文段作为应答,确认序号为收到的 FIN 报文段的序号加 1。客户端进入 TIME_WAIT 状态,经过 2MSL(最长报文段寿命——个报文段在网络中可以存在的最长时间)时间后,连接彻底关闭。服务器收到客户端的 ACK 报文段后,立即关闭连接。

为什么第四次挥手后客户端不直接关闭?

确保最后一个 ACK 报文能够到达服务器:客户端发送的最后一个ACK报文有可能丢失。如果服务器没有收到客户端的确认,就会超时重传FIN报文。客户端在TIME_WAIT状态下等待2MSL时间,就可以有足够的时间接收服务器重传的FIN报文,然后重新发送ACK报文,确保服务器能够正常关闭连接。

防止已失效的连接请求报文出现在新连接中:在网络中,可能存在一些延迟的报文段,这些报文段可能是之前连接的残留。客户端在发送完最后一个ACK报文后,等待2MSL时间,就可以使本连接持续的时间内所产生的所有报文段都消失,这样就可以避免下一个新连接中出现旧的连接请求报文,从而防止历史连接中的数据被后面相同四元组(源 IP 地址、源端口号、目的 IP 地址、目的端口号)的连接错误地接收。

发送缓冲区与接收缓冲区

TCP 流量控制是一种确保发送方发送数据的速率与接收方接收和处理数据的能力相匹配的机制。

在 TCP 中数据发送和接收并不是直接发送与接收,而是先拷贝到内核的发送与接收缓冲区中,由内核决定何时发送。

发送数据过程: 

应用程序调用发送函数(send()或write())将数据写入内核的发送缓冲区。应用程序在数据拷贝完成后就可以继续执行其他任务,不必等待数据真正被发送出去。
内核会根据当前的网络状况、拥塞窗口大小、接收方的通告窗口,来决定何时将发送缓冲区中的数据发送到网络上。

接收数据过程:

当网络中的数据到达主机时,网卡会将数据接收进来,并传递给内核的接收缓冲区。

应用程序通过调用接收函数(如recv()或read())从内核的接收缓冲区中读取数据。如果接收缓冲区中没有数据,应用程序会阻塞等待,直到有数据可读。

流量控制

如果接收端的接收缓冲区满了,发送端继续发送数据,接收端就会将这些数据丢弃。

TCP 报头中有一个字段为16位窗口大小,这个窗口大小就是表示接收方还有多少缓冲区空间可以用于接收数据。

发送方在发送数据时,会根据接收方的接收窗口大小来控制发送的数据量。接收方在收到数据后,会对数据进行处理,并将剩余的接收缓冲区大小通过 TCP 报文段的窗口字段发送给发送方。发送方根据接收方返回的窗口大小,调整自己的发送窗口大小,从而控制发送数据的速率。

当接收端接收缓冲区满时,发送端得知接收端接收数据的能力为0时会停止发送数据,发送端可以通过两种方法得知什么时候可以发送数据:

  • 等待告知:接收端上层将接收缓冲区当中的数据读走后,接收端向发送端发送一个TCP报文,主动将自己的窗口大小告知发送端,发送端得知接收端的接收缓冲区有空间后就可以继续发送数据了。
  • 主动询问:发送端每隔一段时间向接收端发送询问报文,该报文不携带有效数据,只是为了询问发送端的窗口大小,直到接收端的接收缓冲区有空间后发送端就可以继续发送数据了

滑动窗口

在数据发送完成后,在没有收到应答之前,我们需要将数据暂存在发送缓冲区,以便于重传,因此在发送缓冲区中,发送缓冲区可以分为三个部分:

那么已发送未应答部分就是滑动窗口, 滑动窗口的大小就是在未接收到应答时,最大可以发送的数据量,实际发送数据时,在实际发送数据时,发送方不需要依次等待每个数据包的确认应答后再发送下一个数据,而是可以在窗口大小的范围内连续发送多个数据帧。

实际上滑动窗口的意义就是提高发送数据的效率 :

滑动窗口的大小限制了发送方在未收到 ACK 之前能够发送的数据量,既保证了数据的连续发送,提高了信道利用率,又避免了发送方发送过多数据导致接收方处理不过来的情况。

滑动窗口的大小为:接收方接收窗口的大小与当前网络拥塞窗口的大小的较小值。

拥塞控制

TCP 拥塞控制是一种确保网络有效运行的机制,通过调节发送方发送数据的速率,避免网络拥塞,以实现高效、可靠的数据传输。拥塞控制算法如下:

慢启动:开始传输时,拥塞窗口的大小初始化为一个最大报文段(MSS)的大小。拥塞窗口为发送方在没有收到接收方确认之前可以发送的数据量。每收到一个确认报文,拥塞窗口大小加倍,呈指数增长,快速增加发送速率,但增长速度逐渐放缓,防止网络拥塞。

拥塞避免: 当拥塞窗口增长到慢启动阈值()后,进入此阶段。此时,发送方每收到一个确认报文,拥塞窗口增加一个较小的固定值,呈线性增长,使发送速率平稳增加,避免网络拥塞。

拥塞检测与处理:当发送方检测到网络拥塞时,会根据不同的情况采取相应的调整措施。

如果是因为收到三个连续的重复确认报文而检测到拥塞,发送方会执行快速重传和快速恢复算法。快速恢复阶段,将慢启动阈值设置为当前拥塞窗口的一半,然后将拥塞窗口设置为慢启动阈值加上三个最大报文段的大小,接着以线性增长的方式增加拥塞窗口,继续发送数据。

如果是因为超时重传定时器超时而检测到拥塞,发送方会将慢启动阈值设置为当前拥塞窗口的一半,将拥塞窗口重置为一个最大报文段的大小,然后重新进入慢启动阶段。

标签:协议,ACK,报文,TCP,发送,详解,接收,客户端
From: https://blog.csdn.net/2301_80926085/article/details/145093162

相关文章

  • 【计算机网络】传输层协议TCP与UDP
    传输层    传输层位于OSI七层网络模型的第四层,主要负责端到端通信,可靠性保障(TCP),流量控制(TCP),拥塞控制(TCP),数据分段与分组,多路复用与解复用等,通过TCP与UDP协议实现。端到端通信    传输层通过端口号(Port)来区分不同进程。端口号为16位数字(0-65535),用于标......
  • 二叉搜索树详解(看这一篇就够了)
    文章目录二叉搜索树实现树的节点树的结构插入中序遍历查找删除key的搜索场景key/value搜索场景搜索树存在的拷贝和析构的问题二叉搜索树特点:左子树都小于等于根,右子树都大于等于根完全二叉树:h=logN单分支的二叉树:h=N二插搜索树有两个版本,一个冗余的,一个......
  • Web基础与HTTP协议
    Web基础与HTTP协议是现代互联网的核心组成部分,了解它们对于开发和维护高效、可靠的Web应用至关重要。本文将深入探讨Web基础知识和HTTP协议的细节,帮助读者全面理解这些关键概念。一、Web基础1.1Web的工作原理Web是一个由大量互联网页和资源组成的系统,通过互联网将信息传递给用......
  • 字符串哈希详解
    哈希函数的选取通常我们采用的是多项式Hash的方法,对于一个长度为l的字符串s来说,我们可以这样定义多项式Hash函数:其中,M需要选择一个素数(至少要比最大的字符要大),b是一个比最大字符大的整数。(ASCII码值比较)之所以选择这样的哈希函数,不仅是因为它不容易产生哈希碰撞(就......
  • 项目管理-------十大管理-输入-输出-工具和技术详解
    在项目管理的广袤领域中,存在着十大核心知识领域,它们如同精密运转的齿轮,相互协作,共同推动项目从概念走向成功交付。这些管理领域涵盖了项目从启动到收尾的全生命周期,是确保项目顺利进行、达成目标的关键所在。接下来,让我们逐一深入探究这十大管理领域,包括它们的输入、输出、......
  • 【数据库】详解MySQL数据库索引
    目录1.介绍2.索引概述2.1.优缺点3.索引结构3.1.B+Tree索引3.2.Hash索引4.索引分类5.索引语法5.1.创建索引5.2.查看索引5.3.删除索引6.SQL性能分析6.1.慢查询日志6.2.profile详情6.3.explain执行计划7.索引使用7.1索引使用原则7.1.1.最左前缀法则7.1.2.索引......
  • 【C++提高篇】—— C++泛型编程之模板基本语法和使用的详解
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、模板的概念二、函数模板2.1函数模板的使用2.2函数模板注意事项2.3普通函数与函数模板的区别2.4普通函数与函数模板的调用规则2.5模板的局限性三、类模板3.1类模板的使用3.2类模板......
  • TCP 和 UDP
    目录运输层概述TCP和UDP前置知识套接字套接字类型套接字处理过程IP端口号确定端口号多路复用和多路分解无连接的多路复用和多路分解面向连接的多路复用与多路分解UDPUDP特点UDP报文结构TCPTCP报文段结构序号、确认号实现传输可靠性累积确认传输控制利用窗口控制提高速度窗口......
  • Python识别处理验证码技术详解
    目录一、验证码的种类二、OCR技术简介三、使用OCR技术识别验证码1.安装所需库2.下载和处理验证码图片3.使用OCR进行识别4.完整代码示例四、处理复杂验证码五、案例:识别古诗文网验证码六、总结验证码作为一种常见的安全手段,广泛应用于各种网站和应用中,以防止......
  • GBase UCASE 和 UPPER 函数详解
    UCASE 和 UPPER 是两个用于将字符串中的字符转换为大写形式的SQL函数。它们在数据处理、报告生成、文本分析以及各种需要统一字符串格式的场景中非常实用。通过这些函数,用户可以确保数据的一致性,方便后续的比较和分析操作。1. UCASE 和 UPPER 函数的基本语法这两个函数在......