TCP/IP卷一:64---TCP基础之(传输控制协议(TCP)概述、TCP的可靠性、TCP报文格式与封装)
发布日期:2021-06-29 22:33:07 浏览次数:3 分类:技术文章

本文共 5053 字,大约阅读时间需要 16 分钟。

一、TCP概述

  • 虽然TCP和UDP使用相同的网络层(IPv4或IPv6),但是TCP给应用程序提供了一种与UDP完全不同的服务。TCP提供了一种面向连接的、可靠的字节流服务。术语“面向连接的”是指使用TCP的两个应用程序必须在它们可交换数据之前,通过相互联系来建立一个TCP连接。最典型的比喻就是拨打一个电话号码,等待另一方接听 话并说“喂”,然后再说“找谁?”。这正是一个TCP连接的两个端点在互相通信。像广播和组播这些概念在TCP中都不存在

字节流的概念

  • TCP提供一种字节流抽象概念给应用程序使用。这种设计方案的结果是,没有由TCP自动插人的记录标志或消息边界(参阅:)。一个记录标志对应着一个应用程序的写范围指示
  • 例如:如果应用程序在一端写人10字节,随后写人20字节,再随后写人50字节,那么在连接的另一端的应用程序是不知道每次写人的字节是多少的,另一端可能会以每次20字节分四次读入这80字节或以其他一些方式读人。一端给TCP输人字节流,同样的字节流会出现在另一端。每个端点独立选择自己的读和写大小
  • TCP根本不会解读字节流里的字节内容。它不知道正在交换的数据字节是不是二进制数据、 ASCⅡ字符、 EBCDIC字符或其他东西。对这个字节流的解读取决于连接中的每个端点的应用程序。尽管不再推荐使用,可TCP确实是支持以前提到过的紧急机制

二、TCP的可靠性

TCP报文

  • 通过使用刚才描述过的那些技术的特定变种,TCP提供了可靠性
  • 因为它提供一个字节流接口,TCP必须把一个发送应用程序的字节流转换成一组IP可以携带的分组。这被称为组包
  • 这些分组包含序列号,该序列号在TCP中实际代表了每个分组的第一个字节在整个数据流中的字节偏移,而不是分组号。这允许分组在传送中是可变大小的,并允许它们组合,称为重新组包。应用程序数据被打散成TCP认为的最佳大小的块来发送,一般使得每个报文段按照不会被分片的单个IP层数据报的大小来划分
  • 这与UDP不同,应用程序每次写人通常就产生一个UDP数据,其大小就是写人的那么大(加上头部)。由TCP传给IP的块称为报文段(见下面的TCP报文)。在后面的“TCP数据流与窗口管理”的文章中会看到TCP如何判定一个报文段的大小

TCP校验和

  • TCP维持了一个强制的校验和,该校验和涉及它的头部、任何相关应用程序数据和IP 头部的所有字段。
  • 这是一个端到端的伪头部,它用于检测传送中引人的比特差错
  • 如果一个带无效校验和的报文段到达,那么TCP会丢弃它,不为被丢弃的分组发送任何确认。然而,TCP接收端可能会对一个以前的(已经确认的)报文段进行确认,以帮助发送方计算它的拥塞控制
  • TCP校验和使用的数学函数与其他互联网协议(UDP、 ICMP等)一样。 对于大数据的传送,对这个校验和是否不够强壮的担心是存在的[SPOO],所以仔细的应用程序应该应用自已的差错保护方法(如,更强的校验和或CRC),或者使用一种中间层来达到同样的效果

超时重传

  • 当TCP发送一组报文段时,它通常设置一个重传计时器,等待对方的确认接收
  • TCP不会为每个报文段设置一个不同的重传计时器。相反,发送一个窗口的数据,它只设置一个计时器,当ACK到达时再更新超时。如果有一个确认没有及时接收到,这个报文段就会被重传

ACK

  • 当TCP接收到连接的另一端的数据时,它会发送一个确认。这个确认可能不会立即发送,而一般会延迟片刻
  • TCP使用的ACK是累积的,从某种意义来讲,一个指示字节号N的ACK暗示着所有直到N的字节(但不包含N)已经成功被接收了。这对于ACK丢失来说带来了一定的鲁棒性——如果一个ACK丢失,很有可能后续的ACK就足以确认前面的报文段了

三、其他特点

RTT算法

  • TCP含有用于动态估算客户和服务器之间的往返时间(round-trip time,RTT)的算法,以便它知道等待一个确认需要多少时间。举例来说,RTT在一个局域网上大约是几毫秒,跨越一 个广域网则可能是数秒钟。另外,因为RTT受网络流通各种变化因素影响,TCP还持续估算一 个给定连接的RTT

数据的排序与重复丢弃

  • TCP通过给其中每个字节关联一个序列号对所发送的数据进行排序(sequencing)。举例来 说,假设一个应用写2048字节到一个TCP套接字,导致TCP发送2个分节:第一个分节所含数据 的序列号为1~1024,第二个分节所含数据的序列号为1025~2048。(分节是TCP传递给IP的数 据单元。)如果这些分节非顺序到达,接收端TCP将先根据它们的序列号重新排序,再把结果数据传递给接收应用
  • 如果接收端TCP接收到来自对端的重复数据(譬如说对端认为一个分节已丢失并因此重传,而这个分节并没有真正丢失,只是网络通信过于拥挤),它可以(根据序列号) 判定数据是重复的,从而丢弃重复数据

流量控制

  • TCP提供流量控制(flow control)。TCP总是告知对端在任何时刻它一次能够从接收多少字节的数据,这称为通告窗口(advertised window)。在任何时刻,该窗口指出接收缓 冲区中当前可用的空间量,从而确保发送端发送的数据不会使接收缓冲区溢出。该窗口时刻动 态变化:当接收到来自发送端的数据时,窗口大小就减小,但是当接收端应用从缓冲区中读取 数据时,窗口大小就增大。通告窗口大小减小到0是有可能的:当TCP对应某个套接字的接收缓 冲区已满,导致它必须等待应用从该缓冲区读取数据时,方能从对端再接收数据

全双工

  • TCP给应用程序提供一种双工服务。这就是说数据可向两个方向流动,两个方向互相独立
  • 因此,连接的每个端点必须对每个方向维持数据流的一个序列号。一旦建立了一个连接,这个连接的一个方向上的包含数据流的每个TCP报文段也包含了相反方向上的报文段的一个ACK
  • 每个报文段也包含一个窗口通告以实现相反方向上的流量控制。为此,在一 个连接中,当一个TCP报文段到达时,窗口可能向前滑动,窗口大小可能改变,同时新数 据可能已到达
  • 在后面的TCP连接管理文章中可以看到,一个完整的TCP连接是双向和对称的,数据可以在两个方向上平等地流动

序列号

  • 使用序列号,一个TCP接收端可丢弃重复的报文段和记录以杂乱次序到达的报文段。 回想一下,任何反常情况都会发生,因为TCP使用IP来传递它的报文段,IP不提供重复消除或保证次序正确的功能
  • 然而,因为TCP是一个字节流协议,TCP绝不会以杂乱的次序给接收应用程序发送数据。因此,TCP接收端可能会被迫先保持大序列号的数据不交给应用程序,直到缺失的小序列号的报文段(一个“洞”)被填满

四、TCP与UDP的区别

  • UDP不提供可靠性。UDP本身不提供确认、序列号、RTT估算、超时和重传等机制。如 果一个UDP数据报在网络中被复制,两份副本就可能都递送到接收端的主机。同样地,如果 一个UDP客户发送两个数据报到同一个目的地,它们可能被网络重新排序,颠倒顺序后到达 目的地。UDP应用必须处理所有这些情况
  • UDP不提供流量控制,让较快的UDP发送端以一个UDP接收端 难以跟上的速率发送数据报是非常容易的
  • UDP可以是全双工的

五、TCP报文段的封装

  • TCP可以与IPv4或IPv6一起使用,同时它使用的伪头部(与UDP的类似)在IPv4或IPv6总都是强制使用的

六、TCP头部

源端口、目的端口

  • 每个TCP头部包含了源和目的端口号。这两个值与IP头部中的源和目的IP地址一起,唯一地标识了每个连接
  • 在TCP术语中,一个IP地址和一个端口的组合有时被称为一个端点或套接字。后者出现在[RFCO793]中,最终被Berkeley系列的网络通信编程接口所采用(现在经常被称为“Berkeley套接字” )

序列号

  • 序列(Sequence Number)字段标识了TCP发送端到TCP接收端的数据流的一个字节,该字节代表着包含该序列号的报文段的数据中的第一个字节
  • 如果我们考虑在两个应用程序之间的一个方向上流动的数据流,TCP给每个字节赋予一个序列号。这个序列号是一 个32位的无符号数,到达2^{32}-1后再循环回到0

确认号

  • 通过序列号我们知道每个被交换的字节都已编号,确认号字段(也简称ACK号或ACK字段)包含的值是该确认号的发送方期待接收的下一个序列号。即最后被成功接收的数据字节的序列号加1
  • 这个字段只有在ACK位字段被启用的情况下才有效,这个ACK位字段通常用于除了初始和末尾报文段之外的所有报文段。发送一个ACK与发送任何一个TCP报文段的开销是一样的,因为那个32位的ACK号字段一直都是头部的一部分,ACK位字段也一样
  • 当建立一个新连接时,从客户机发送至服务器的第一个报文段的SYN位字段被启用。 这样的报文段称为SYN报文段,或简单地称为SYN。然后序列号字段包含了在本次连接的这个方向上要使用的第一个序列号,后续序列号和返回的ACK号也在这个方向上(回想一 下,连接都是双向的)。注意这个数字不是0和1,而是另一个数字,经常是随机选择的,称为初始序列号(ISN)。ISN不是0和1,是因为这是一种安全措施(在后面“TCP连接管理”中介绍)。发送在本次连接的这个方向上的数据的第一个字节的序列号是ISN加1,因为SYN位字段会消耗一个序列号。正如我们稍后将见到的,消耗一个序列号也意味着使用重传进行可靠传输。因此,SYN和应用程序字节(还有FIN,稍后我们将会见到)是被可靠传输的。不消耗序列号的ACK则不是

头部长度

  • 头部长度字段给出了头部的长度,以32位字为单位
  • 它是必需的,因为选项字段的长度是可变的。作为一个4位的字段,TCP被限制为只能带60字节的头部。如果不带选项,大小是20字节

8位字段

  • 当前,为TCP头部定义了8位的字段,尽管一些老的实现只理解它们中的最后6位。它们中的一个或多个可被同时启用。我们在这里大致提一下它们的用法,在后面再对每个进行详细的讨论
  • 1. CWR——拥塞窗口减(发送方降低它的发送速率);见后面“TCP拥塞控制”
  • 2. ECE——ECN回显(发送方接收到了一个更早的拥塞通告);见后面“TCP拥塞控制”
  • 3. URG——紧急(紧急指针字段有效——很少被使用); (见:)
  • 4.ACK——确认(确认号字段有效——连接建立以后一般都是启用状态);见后面“TCP连接管理”和“TCP数据流与窗口管理”
  • 5. PSH——推送(接收方应尽快给应用程序传送这个数据一没被可靠地实现或用到);(见:)
  • 6. RST——重置连接(连接取消,经常是因为错误);见后面“TCP连接管理”
  • 7. SYN——用于初始化一个连接的同步序列号;(见:)
  • 8. FIN——该报文段的发送方已经结束向对方发送数据;见后面“TCP连接管理”

窗口大小

  • TCP的流量控制由每个端点使用窗口大小字段来通告一个窗口大小来完成
  • 这个窗口大小是字节数,从ACK号指定的,也是接收方想要接收的那个字节开始
  • 这是一个16位的字段,限制了窗口大小到65535字节,从而限制了TCP的吞吐量性能
  • 在后面“TCP数据流与窗口管理”的文章中,我们将看到窗口缩放选项可允许对这个值进行缩放,给高速和大延迟网络提供了更大的窗口和改进性能

TCP校验和

  • TCP校验和字段覆盖了TCP的头部和数据以及头部中的一些字段,使用一个与我们在前面讨论的ICMPv6与UDP使用的相类似的伪头部进行计算
  • 这个字段是强制的,由发送方进行计算和保存,然后由接收方验证
  • TCP校验和的计算算法与IP、 ICMP和 UDP(“互联网”)校验和一样

紧急指针

  • 紧急指针字段只有在URG位字段被设置时才有效
  • 这个“指针”是一个必须要加到报文段的序列号字段上的正偏移,以产生紧急数据的最后一个字节的序列号
  • TCP的紧急机制是一种让发送方给另一端提供特殊标志数据的方法

选项

  • 选项字段在后面文章介绍
  • 最常见的选项字段就是“最大段大小”选项,称为MSS。连接的每个端点一般在它发送的第一个报文段(为了建立该连接,SYN位字段被设置的那个报文段)上指定这个选项,MSS指定该选项的发送者在相反方向上希望接收到的报文段的最大值。在“TCP连接管理”中,我们将更详细地描述MSS选项
  • 在“TCP超时与重传”与“TCP数据流与窗口管理”中,我们将描述其他一些TCP选项。我们考查的其他普通选项还包括SACk、时间戳和窗口缩放

转载地址:https://dongshao.blog.csdn.net/article/details/104016416 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Linux(内核剖析):27---中断下半部之(下半部机制的选择、在下半部之间加锁、禁止下半部(local_bh_disable、local_bh_enable))
下一篇:TCP/IP卷一:63---TCP基础之(ARQ和重传、分组窗口和滑动窗口、流量控制和拥塞控制、设置重传超时)

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2024年04月26日 01时20分42秒