TCP简介

上一篇文章,我们讲了UDP。UDP最大的缺点就是无法提供可靠数据传输,这使得数据发送出去之后可能丢失。在一些对数据完整性要求十分严格的场景下,UDP就无用武之地了。而TCP就是用来解决数据完整传输这一问题的。


--图 泰国TCP Group(เกี่ยวกับ TCP),貌似是卖饮料的。

TCP是因特网传输层的面向连接可靠数据传输。为了实现可靠数据传输,TCP使用了许多措施:差错检测、超时重传、累积确认、定时器以及用于序号和确认号的首部字段

可靠数据传输机制

机制 用途和说明
检验和 用于监测在一个传输分组中的比特错误
定时器 用于超时/重传一个分组,可能因为该分组(或其ACK)在信道中丢失了.由于当一个分组延时但未丢失,或当一个分组已被接收方接收但从接收方到发送方的ACK丢失时,可能产生超时事件,所以接收方可能会收到一个分组的多个冗余副本.
序号 用于为从发送方流向接收方的数据分组按序号编号.所接受分组的序号的空隙可是的接收方检测除丢失的分组.具有相同序号的分组可使接收方检测出一个分组的冗余副本.
确认 接收方用于告诉发送方一个分组或一组分组已经被正确地接收到了.确认报文通常携带着被确认的分组或多个分组的序号.确认可以是逐个的或积累的,这取决于协议.
否定确认 收方用于告诉发送方某个分组未被正确的接收.否则人确定报文通常携带着未被正确接收的分组的序号.
窗口、流水线 发送方也许被限制仅发送那些序号落在一个指定范围内的分组.通过允许一次发送多个分组但未被确认,发送方的利用率可以在停等操作模式上得到增加.我们很快将会看到,窗口长度可根据接收方接收和缓存报文的能力/网络中的拥塞程度或两者的情况来进行设置.

在这里,我首先给出TCP可靠数据传输所采取的机制,关于这些机制的原理我后面还会有陆续几篇文章介绍。

TCP通信的过程

TCP是面向连接的,这是因为在一个应用进程可以开始向另一个应用进程发送数据之前,这两个进程必须先相互“握手”,即它们必须先相互发送某些预备报文段,以建立确保数据传输的参数。在握手的过程中,连接的双方都将初始化与TCP连接的许多TCP状态变量,例如初始化发送缓存和接收缓存,交换确定彼此的序号和确认号等

一旦建立起一条TCP连接,两个应用进程之间就可以相互发送数据了。在介绍发送接收数据之前我们先介绍TCP连接的两个基本特点:

  • TCP连接提供的是全双工服务
    如果一台主机上的进程A与另一台主机上的进程B存在一条TCP连接,那么应用层数据可以在从进程B流向进程A的同时,也从进程A流向进程B。
  • TCP连接是点对点的
    也即是TCP连接是单个发送方和单个接收方之间的连接。多播(在一次发送操作中,从一个发送方将数据传送给多个接收方)对于TCP来说是不可能的。

我们考虑一下从客户进程向服务进程发送数据的情况。客户端进程通过套接字(该进程之门)传递数据流。数据一旦通过该门,它就由客户端中运行的TCP控制了.TCP经这些数据引导到该链接的发送缓存里,发送缓存是在三次握手初期设置的设置的缓存之一。接下来TCP就会不时从发送缓存里取出一块数据。取出数据的大小受限于最大报文段长度(Maximum Segment Size,MSS)。然后,TCP会为每块应用层数据配上一个TCP首部,从而形成多个TCP报文段,这些报文段被下传到网络层,网络层将其封装在网络层的IP数据包中,然后这些IP数据报被发送到网络中。当TCP在另一端接收到一个报文段后,该报文段的数据就被放入该TCP连接的接收缓存,应用程序从此缓存中读取数据流。由于TCP提供的是全双工服务,所以TCP连接的每一端都有各自的发送缓存和接收缓存

由上面的讨论我们可以看出,TCP连接的组成包括:一台主机上的缓存、变量和与进程连接的套接字,以及另一台主机上的另一组缓存、变量和与进程连接的套接字。两台主机之间的网络元素(路由器、交换机和中继器)没有为该TCP连接分配任何缓存与变量。

TCP报文段结构

为了便于后面介绍TCP可靠数据传输的实现,这里我们先介绍一下TCP报文段的结构:

TCP报文段由首部字段和一个数据字段组成。数据字段包含一块应用数据。如前所述,MSS限制报文段数据字段的最大长度。当TCP发送一个大文件时,通常是将该文件划分为长度为MSS的若干块(最后一块除外,它通常小于MSS).然而对于很多交互式应用来说,其TCP报文的数据字段通常很小。例如像Telnet这样的远程登录应用,其TCP报文段的数据字段经常只有一个字节,由于TCP的首部一般是20个字节(比UDP首部多12字节),所以Telnet发送的报文段也许只有21字节。

如上图,TCP报文段由下列部分组成:

  • 源端口号(source port)和目的端口号(dest port)
    被用来多路复用/分解来自或送到上层应用的数据。协助实现进程间的数据交付功能。

  • 检验和字段(checksum)
    同UDP一样,检验和字段也是用来检查报文中可能发生的比特错误。

  • 32比特的序号字段(sequence number)和32比特的确认号字段(acknowledgement number)
    这两个字段被TCP发送方和接收方用来实现可靠数据传输服务。

  • 16比特的接收窗口字段(receive window)
    该字段用来实现流量控制,即匹配发送方的发送速度与接收方的接收速度。

  • 4比特的首部长度字段
    该字段指示了以32比特的字为单位的TCP首部长度。由于TCP选项字段的原因,TCP首部字段的长度是可变的,所以发送方需要计算首部的长度,以方便接收方处理。

  • 可选与变长的选项字段(options,variable length)
    该字段用于发送方与接收方协商最大报文段长度时,或者在高速网络环境下用作窗口调节因子时使用

  • 6比特的标志字段(flag field)
    标志字段的6个比特分别为:URG、ACK、PSH、RST、SYN、FIN。ACK比特置为1,则表明这是一个确认报文,包含一个对已成功接收报文段的确认。RST、SYN、FIN用于连接的建立和拆除。当PSH比特设置为1,就指示接收方应立即将数据交给上层。URG比特用来指示报文段里存在着被发送端上层的实体置为紧急的数据,紧急数据的最后一个字节由16比特的应急数据指针指出。当紧急数据存在并给定指向紧急数据尾的指针的时候,TCP必须通知接收端的上层实体。(在实践中,PSH,URG和紧急数据指针并没有使用。为了讨论的完整性,这里才提到这些字段)

了解TCP报文段的结构对于后面我们讨论TCP可靠数据传输来说至关重要。

结论

  • TCP是因特网传输层的面向连接的可靠数据传输。
  • TCP为了实现可靠数据传输,采用了:差错检测、超时重传、累积确认、定时器以及用于序号和确认号的首部字段等措施。
  • TCP连接提供的是全双工服务,点对点通信。“多播”对TCP协议来说是不可能的。
  • TCP在通信之前需要先握手,以初始化与TCP连接的许多TCP状态变量。这也是TCP称为面向连接的原因。
  • TCP连接的每一端都有各自的发送缓存和接收缓存。
  • TCP连接的组成包括:一台主机上的缓存、变量和与进程连接的套接字,以及另一台主机上的另一组缓存、变量和与进程连接的套接字。
  • TCP报文段由首部字段和一个数据字段组成,数据字段的大小受限于最大报文段长度(MSS)。
  • TCP报文由源端口号(source port)和目的端口号(dest port)、检验和字段(checksum)、32比特的序号字段(sequence number)和32比特的确认号字段(acknowledgement number)、16比特的接收窗口字段(receive window)、4比特的首部长度字段、可选与变长的选项字段(options,variable length)、6比特的标志字段(flag field)等部分组成。