网络运输层之(1)TCP协议基础

打印 上一主题 下一主题

主题 983|帖子 983|积分 2949

网络运输层之(1)TCP协议基础

  
   Author: Once Day Date: 2024年9月12日


  一位热衷于Linux学习和开发的菜鸟,试图谱写一场冒险之旅,也许终点只是一场白日梦…


   漫漫长路,有人对你微笑过嘛…


  全系列文章可参考专栏: 通讯网络技能_Once-Day的博客-CSDN博客。


  参考文章:
  

  • 《TCP/IP详解卷一》
  • TCP协议详解 (史上最全)-CSDN博客
  • TCP协议详解 - 知乎 (zhihu.com)
  • 计算机网络:这是一份非常全面&详细的TCP/IP协议学习指南-腾讯云开发者社区-腾讯云 (tencent.com)
  • 计算机网络原理梳理丨清晰认识 TCP/IP 协议-腾讯云开发者社区-腾讯云 (tencent.com)
  

  
1. 概述

1.1 介绍

传输控制协议(Transmission Control Protocol,TCP)是一种面向毗连的、可靠的、基于字节省的传输层通讯协议。它是当今互联网中最广泛使用的传输协议之一,为各种网络应用程序提供了可靠的数据传输服务。
TCP协议在传输数据时,会将数据分成一个个的报文段(segment)举行传输。每个报文段都包含了源端标语、目的端标语、序列号、确认号、控制位等重要信息,以确保数据传输的可靠性和有序性。
TCP协议的发展历程可以追溯到20世纪70年代末,颠末几十年的演变和完善,已经成为当今互联网中最重要的传输层协议之一。TCP协议的发展大抵经历了以下几个阶段:

  • 初始规范阶段(20世纪80年代):TCP协议的原始规范RFC 793发布,奠定了TCP的基本功能和特性,如面向毗连、可靠传输和全双工通讯等。随后,RFC 1122对TCP规范举行了修订和完善。
  • 性能优化阶段(20世纪90年代):为了顺应互联网的快速发展,TCP引入了多项性能优化措施,如RFC 1323中的窗口缩放、时间戳和PAWS算法,以及RFC 2018中的选择性确认(SACK)机制,用于提高TCP在高速、长间隔网络中的性能和可靠性。
  • 拥塞控制阶段(20世纪90年代末至21世纪初):TCP拥塞控制算法的不断完善和成熟,从RFC 2581到RFC 5681,奠定了现代TCP拥塞控制的基础。同时,RFC 3168引入了显式拥塞通知(ECN)机制,答应网络向TCP反馈拥塞信息。
  • 高性能扩展阶段(21世纪10年代):为了进一步提高TCP在高速、长间隔网络中的性能,RFC 7323对TCP的高性能扩展举行了更新,包罗窗口缩放、时间戳和PAWS算法等。
  • 现代TCP规范阶段(21世纪10年代至今):RFC 8312作为当前最新的TCP规范文档,对TCP的各个方面举行了全面的形貌和规范,是当前TCP协议的权威参考。
1.2 服务模型

TCP协议的重要特点如下:


  • 面向毗连:在数据传输之前,TCP通讯的双方必须先建立毗连,确保双方都准备好举行数据交换。
  • 可靠性:TCP使用序列号、确认应答、重传等机制来确保数据的可靠传输,保证数据不会丢失、重复或乱序。
  • 字节省:TCP将应用程序传输的数据视为一连串的字节省,不关心字节省的具体含义,只负责把数据从一端传送到另一端。
  • 全双工:TCP支持全双工通讯,即数据可以同时在两个方向上传输,双方都可以同时发送和接收数据。
  • 流量控制:TCP通过滑动窗口机制实现流量控制,防止发送方发送数据的速率超过接收方接收数据的速率,避免网络拥塞。
  • 拥塞控制:TCP采用拥塞控制算法,如慢启动、拥塞避免、快速重传和快速恢复等,来顺应网络拥塞状态,调解发送速率,提高网络利用率。
1.3 RFC文档

下面是TCP相关的RFC文档:


  • RFC 793 - Transmission Control Protocol (1981),TCP协议的原始规范,界说了TCP的基本功能和报文格式。
  • RFC 1122 - Requirements for Internet Hosts - Communication Layers (1989),对TCP的规范举行了修订和完善,提出了许多新的要求和建议。
  • RFC 1323 - TCP Extensions for High Performance (1992),引入了窗口缩放、时间戳和PAWS算法,用于提高TCP在高速、长间隔网络中的性能。
  • RFC 2018 - TCP Selective Acknowledgment Options (1996),界说了TCP选择性确认(SACK)选项,用于改进TCP的丢包恢复本领。
  • RFC 2581 - TCP Congestion Control (1999),对TCP拥塞控制算法举行了详细形貌,包罗慢启动、拥塞避免、快速重传和快速恢复等算法。
  • RFC 2883 - An Extension to the Selective Acknowledgement (SACK) Option for TCP (2000),引入了D-SACK(Duplicate SACK),用于检测网络中的数据包重复征象。
  • RFC 3168 - The Addition of Explicit Congestion Notification (ECN) to IP (2001),界说了显式拥塞通知(ECN)机制,答应路由器向TCP发送方反馈网络拥塞信息。
  • RFC 3390 - Increasing TCP’s Initial Window (2002),提出了增加TCP初始窗口巨细的建议,以提高TCP在短流量传输中的性能。
  • RFC 3782 - The NewReno Modification to TCP’s Fast Recovery Algorithm (2004),对TCP快速恢复算法举行了修改,提出了NewReno算法,改进了TCP的丢包恢复性能。
  • RFC 4138 - Forward RTO-Recovery (F-RTO): An Algorithm for Detecting Spurious Retransmission Timeouts with TCP and the Stream Control Transmission Protocol (SCTP) (2005),提出了F-RTO算法,用于检测和处理TCP中的虚伪超时重传问题。
  • RFC 5681 - TCP Congestion Control (2009),对TCP拥塞控制算法举行了修订和完善,融合了之前多个RFC文档中的内容。
  • RFC 6298 - Computing TCP’s Retransmission Timer (2011),介绍了计算TCP重传计时器的算法和方法。
  • RFC 6582 - The NewReno Modification to TCP’s Fast Recovery Algorithm (2012),对RFC 3782中的NewReno算法举行了更新和完善。
  • RFC 7323 - TCP Extensions for High Performance (2014),对TCP的高性能扩展举行了更新,包罗窗口缩放、时间戳和PAWS算法等。
  • RFC 7413 - TCP Fast Open (2014),介绍了TCP快速打开(TFO)机制,用于减少TCP毗连建立的延迟。
  • RFC 8312 - CUBIC for Fast Long-Distance Networks (2018),介绍了CUBIC拥塞控制算法,实用于高速、长间隔网络。
2. 报文协议

2.1 TCP报文格式

TCP报文(也称为TCP段,segment)是TCP协议通讯过程中传输的数据单位,每个TCP报文都由报文头部和数据部分构成。

下面是各个字段的含义:


  • 源端口(Source Port,16位):表示发送TCP报文的源端标语。
  • 目的端口(Destination Port,16位):表示接收TCP报文的目的端标语。
  • 序列号(Sequence Number,32位):表示当前报文段中第一个字节的序号。TCP给每个字节都赋予了一个序列号,这是一个32位的无符号数字,到达                                                         2                                  32                                          −                               1                                      2^{32}-1                        232−1后再循环到0,每个被交换的字节都已编号。
  • 确认号(Acknowledgment Number,32位):表示期望接收的下一个字节的序号,也就是当前已成功接收的字节序号加1。
  • 数据偏移(Data Offset,4位):表示TCP报文头部的长度,单位为4字节。
  • 保留位(Reserved,4位):保留字段,供未来使用。
  • 控制位(Control Bits,8位):包罗CWR,ECE,URG、ACK、PSH、RST、SYN和FIN。

    • CWR:拥塞窗口减少,用于发送方降低它的发送速率。
    • ECE:ECN回显,发送方接收到了一个更早的拥塞通告。
    • URG:紧急指针(Urgent Pointer),较少使用。
    • ACK:确认号(Acknowledgment Number)字段有效,毗连建立之后一样平常都默认启用,也就是除了初始和末尾报文段之外的全部报文。
    • PSH:接收方应尽快将数据传递给应用程序。
    • RST:重置毗连,常常由于错误取消毗连。
    • SYN:同步序号,用于初始化毗连。
    • FIN:发送方已经完成数据发送。

  • 窗口巨细(Window Size,16位):表示接收方当前可接收的字节数,用于流量控制。这个字段最大值是65535,可以通过窗口缩放选项(Window Scale)对其举行缩放,从而提供更高的上限值。
  • 校验和(Checksum,16位):用于查验TCP报文头部和数据部分的完备性。
  • 紧急指针(Urgent Pointer,16位):当URG标志位置1时有效,指示紧急数据的末尾在报文段中的位置。
  • 选项(Options,可变长度):TCP头部的可选字段,用于实现一些特殊功能,如最大报文段长度(MSS)、窗口缩放因子、时间戳等。
  • 添补(Padding,可变长度):用于确保TCP头部长度为4字节的整数倍。
2.2 TCP校验和

TCP校验和是TCP报文头部中的一个重要字段,用于验证TCP报文在传输过程中是否出现了误码或破坏。
TCP伪头部是计算校验和时使用的一个虚拟头部,它包含了一些来自IP头部的信息。伪头部的格式如下:

校验和的计算方式如下(与IP、ICMP和UDP协议类似)

  • 将TCP伪头部、TCP头部和数据部分看作一个一连的字节省
  • 将字节省划分为16位(2字节)的字
  • 假如字节省的长度为奇数,在末尾添加一个全零字节,使字节省长度变为偶数
  • 将全部16位字相加,得到一个32位的和
  • 将32位的和的高16位与低16位相加,得到一个16位的和
  • 将16位的和取反,得到TCP校验和的值
接收方在收到TCP报文后,会按照雷同的方法计算校验和,并与报文中的校验和字段举行比较。假如两者雷同,阐明报文在传输过程中没有出现差错;假如不同,则阐明报文在传输过程中出现了差错,需要举行重传或错误处理。
但这种校验和对于超大量数据来说,仍旧是不够结实,应用层仍旧需要采取自界说的本领来保证应用层数据可靠性
2.2 三次握手

TCP是一种面向毗连的可靠传输协议,在通讯双方举行数据传输之前,需要先建立毗连。TCP使用三次握手(Three-Way Handshake)的方式来建立毗连,下面是示意图:

(1) 第一次握手(SYN),客户端向服务器发送一个SYN(同步)报文:


  • 设置SYN标志位为1,表示这是一个毗连请求报文。
  • 随机生成一个初始序列号(ISN,Initial Sequence Number),例如ISN=X。
  • 可选地携带其他参数,如最大报文段长度(MSS)等。
(2) 第二次握手(SYN+ACK),服务器收到客户端的SYN报文后,假如同意建立毗连,则返回一个SYN+ACK报文:


  • 设置SYN标志位为1,ACK标志位为1,表示这是一个毗连接受报文。
  • 服务器也随机生成一个初始序列号,例如ISN=Y。
  • 确认号(Acknowledgment Number)设置为客户端的ISN加1,即Ack=X+1。
  • 可选地携带其他参数。
(3) 第三次握手(ACK),客户端收到服务器的SYN+ACK报文后,向服务器发送一个ACK报文:


  • 设置ACK标志位为1,表示这是一个确认报文。
  • 序列号(Sequence Number)设置为客户端的ISN加1,即Seq=X+1。
  • 确认号设置为服务器的ISN加1,即Ack=Y+1。
  • 可选地携带其他参数或数据。
2.3 四次挥手

当客户端或服务器任一方需要关闭TCP毗连时,就会启动毗连释放的过程。TCP使用四次挥手(Four-Way Handshake)的方式来释放毗连,下面是示意图:

(1) 第一次挥手(FIN),假设客户端先发起毗连释放,客户端向服务器发送一个FIN(停止)报文:


  • 设置FIN标志位为1,表示这是一个毗连释放请求报文。
  • 序列号(Sequence Number)设置为当前的序列号,例如Seq=X。
(2) 第二次挥手(ACK),服务器收到客户端的FIN报文后,向客户端发送一个ACK报文:


  • 设置ACK标志位为1,表示这是一个确认报文。
  • 确认号(Acknowledgment Number)设置为客户端的序列号加1,即Ack=X+1。
(3) 第三次挥手(FIN),服务器完成数据发送后,也向客户端发送一个FIN报文:


  • 设置FIN标志位为1,表示这是一个毗连释放请求报文。
  • 序列号设置为当前的序列号,例如Seq=Y。
(4) 第四次挥手(ACK),客户端收到服务器的FIN报文后,向服务器发送一个ACK报文:


  • 设置ACK标志位为1,表示这是一个确认报文。
  • 确认号设置为服务器的序列号加1,即Ack=Y+1。
留意,客户端在进入CLOSED状态之前,需要颠末TIME_WAIT状态,并期待2MSL的时间。如许做的目的是确保网络中全部的报文都已经被接收或丢弃,防止新毗连误接收旧毗连的报文
2.4 自动重传

在数据通讯中,由于各种缘故原由(如信道噪声、网络拥塞等),数据报文在传输过程中可能会出现丢失、破坏或重复等问题。为了确保数据的可靠传输,通讯双方通常使用自动重复请求(Automatic Repeat reQuest,ARQ)机制和自动重传功能。
自动重复请求是一种在通讯双方之间实现可靠数据传输的方法,它要求接收方在收到数据后向发送方发送确认(ACK),假如发送方在肯定时间内未收到确认,则认为数据丢失并重新发送。ARQ重要有以下三种方式:


  • 停止期待ARQ(Stop-and-Wait ARQ):发送方每发送一个数据包就停止发送,期待接收方的确认,收到确认后再发送下一个数据包。
  • 回退N帧ARQ(Go-Back-N ARQ):发送方可以一连发送多个数据包,假如接收方发现有数据包丢失,则要求发送方重传丢失的数据包及其后的全部数据包。
  • 选择重传ARQ(Selective Repeat ARQ):发送方可以一连发送多个数据包,假如接收方发现有数据包丢失,则只要求发送方重传丢失的数据包,而不影响其他正确接收的数据包。
TCP采用了一种基于选择重传ARQ的自动重传机制,以确保数据的可靠传输


  • 超时重传(Timeout Retransmission):当发送方发送了一个数据包后,会启动一个计时器。假如在计时器超时之前没有收到接收方的确认,发送方就会重新发送这个数据包。
  • 快速重传(Fast Retransmission):当接收方收到一个失序的数据包时,会立即发送一个重复的ACK(纵然还没有收到期望的数据包)。当发送方收到三个或更多个重复的ACK时,会立即重传对应的数据包,而不期待计时器超时。
  • 选择确认(Selective Acknowledgment,SACK):SACK是TCP的一个可选扩展,它答应接收方在ACK中指明已经成功接收的数据包的范围,如许发送方就可以只重传丢失的数据包,提高了重传的服从。
  • 重传超时时间(Retransmission Timeout,RTO)的计算:TCP根据网络的往返时间(Round-Trip Time,RTT)和RTT的变革情况,动态地计算重传超时时间,以顺应网络状态的变革。
2.5 流量控制(滑动窗口)

在TCP通讯中,滑动窗口(Sliding Window)是一种用于实现流量控制的机制。它答应发送方根据接收方的接收本领动态调解发送数据的速率,以避免接收方的缓冲区溢出或网络拥塞。
滑动窗口是指在任意时刻,发送方可以发送的数据范围。这个范围由两个指针界定:发送窗口的左边界和右边界。左边界表示已经发送并得到确认的数据的最大序号,右边界表示可以发送的数据的最大序号
窗口的巨细由接收方通告的窗口巨细(rwnd,Receiver Window)决定。发送方的发送窗口不能超过rwnd,以防止发送过多的数据导致接收方的缓冲区溢出。
随着数据的发送和确认,滑动窗口会不断向右移动,答应发送方发送新的数据。这就是"滑动窗口"的由来。
TCP使用滑动窗口实现了流量控制,具体过程如下:

  • 接收方在ACK报文中通告自己的接收窗口巨细(rwnd),表示自己当前可以接收的数据量。
  • 发送方根据接收方通告的rwnd和自己的拥塞窗口(cwnd,Congestion Window)计算发送窗口的巨细,取两者的最小值:
    1. send_window = min(rwnd, cwnd)
    复制代码
  • 发送方只能在发送窗口答应的范围内发送数据,即已发送但未确认的数据量不能超过发送窗口的巨细。
  • 当接收方处理了一部分数据后,其接收缓冲区空出了空间,就会通过ACK报文通告更大的rwnd,答应发送方发送更多的数据。
  • 假如接收方的接收缓冲区满了,会通告一个零的rwnd,发送方就必须停止发送数据,直到接收方再次通告非零的rwnd。
TCP的滑动窗口机制可以动态调解发送速率,使其与接收方的接收本领相匹配,从而实现了流量控制
2.6 拥塞控制

除了流量控制,TCP还具有拥塞控制(Congestion Control)的功能,用于防止网络拥塞和崩溃。拥塞控制答应TCP在网络拥塞时调解发送速率,以避免进一步加剧拥塞,并在网络恢复后逐步增加发送速率。
TCP使用拥塞窗口(Congestion Window,cwnd)来控制发送速率。拥塞窗口表示在任意时刻,发送方可以发送的未确认数据的最大量。与接收方通告的接收窗口(rwnd)不同,拥塞窗口是发送方根据网络拥塞状态自行调解的
发送窗口的巨细由拥塞窗口和接收窗口共同决定:
  1. send_window = min(cwnd, rwnd)
复制代码
TCP采用了慢启动(Slow Start)和拥塞避免(Congestion Avoidance)两种算法来调解拥塞窗口的巨细


  • 慢启动:当毗连建立时,cwnd初始化为一个小值(通常为1个MSS,最大段巨细)。每收到一个ACK,cwnd就增加1个MSS,这导致cwnd以指数方式增长。当cwnd达到慢启动阈值(ssthresh)时,进入拥塞避免阶段。
  • 拥塞避免:在拥塞避免阶段,每收到一个ACK,cwnd增加1/cwnd个MSS。这导致cwnd以线性方式缓慢增长,直到出现拥塞事件(如超时或收到重复ACK)。
  • 快速重传和快速恢复:当收到三个或更多重复ACK时,TCP执行快速重传,立即重传丢失的数据包。同时,执行快速恢复,将ssthresh设置为当前cwnd的一半,并将cwnd设置为ssthresh加上3个MSS,然后进入拥塞避免阶段。
  • 超时:假如发生超时,TCP将ssthresh设置为当前cwnd的一半,将cwnd重置为1个MSS,然后重新进入慢启动阶段。
通过这些算法,TCP可以在网络拥塞时迅速降低发送速率,在网络恢复后逐步提高发送速率,从而实现了拥塞控制。
除了上述基本的拥塞控制算法,TCP还有一些其他的拥塞控制算法,如:


  • TCP Tahoe:上述基本算法的原始版本。
  • TCP Reno:在快速恢复后,假如收到部分ACK,则退出快速恢复并进入拥塞避免阶段。
  • TCP NewReno:改进了快速恢复算法,可以处理多个数据包丢失的情况。
  • TCP Vegas:基于延迟而不是丢包来检测拥塞,试图在队列积累之前就降低发送速率。
  • TCP CUBIC:目前在Linux体系中使用的默认拥塞控制算法,使用立方函数来调解cwnd,实用于高带宽、高延迟的网络。







   Once Day

  

    也信尤物终作土,不堪幽梦太匆匆......
    假如这篇文章为您带来了资助或启发,不妨点个赞

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

耶耶耶耶耶

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表