TCP是因特网运输层的面向连接的可靠的运输协议。为了提供可靠数据传输,TCP依赖于差错控制,重传,累积确认,定时器以及用于序号和确认号的首部字段。
TCP被称为是面向连接的,这是因为在一个应用程序可以开始向另一个应用进程发送数据之前,这两个进程必须先相互“握手”,即他们必须相互发送某些预备子弹,以及确保数据传输的参数。作为TCP连接建立的一部分,连接的双方都将初始化与TCP连接相关的许多TCP状态变量。
TCP连接状态完全保留在两个端系统之中,由于TCP协议只能在端系统中运行,而不再中间的网络元素(路由器和链路层交换机)中运行,所以中间的网络元素不会维持TCP连接状态。事实上,中间路由器对TCP连接完全视而不见,他们看到的是数据报而不是连接。
TCP连接提供的是全双工服务,如果一台主机上的进程A与另外一台主机上进程B存在一条TCP连接,那么应用层数据就可以从进程B流向进程A的同时,也从进程A流向进程B。TCP连接也总是点对点的,即在单个发送方与单个接收方之间连接。
TCP连接的建立也是有自己的特点的。假设运行在某台主机上的一个进程想与另外一台主机上的一个进程建立一条连接。发起连接的这个进程被称为客户进程,而另外一个进程被称为服务器进程。该客户应用进程首先要通知客户运输层,他想去服务器的一个进程建立一条连接。客户首先发送一个特殊的TCP报文段,服务器用另外一个特殊的TCP报文段来响应,最后,客户再通过第三个特殊报文段作为响应。前两个报文段不承载“有效载荷”,也就是不包含应用层数据;而第三个报文段可以承载有效载荷。由于这两台主机之间发送了3个报文段,所以这种连接的建立过程常备称为三次握手。
一旦建立一条TCP连接,两个应用进程之间就可以相互发送数据了。从客户进程向服务器发送数据时,客户进程通过套接字传送数据流。数据一旦通过该门,它就由客户中运行的TCP控制,TCP将这些数据引导到该连接的发送缓存里,发送缓存是在三次握手初期设置的缓存质疑,接下来TCP就会不时的从发送缓存里取数一块数据。TCP可从缓存中取出并放入报文段中的数据数量受限于最大报文段长度(MSS)MSS通常根据最初确定的由本地发送主机发送的最大链路层帧长度来设置。
TCP为每块客户数据都配上一个TCP首部,从而形成多个TCP报文段。这些报文段被传给网络层,网络层将其封装在网络层IP数据报中。然后这些IP数据报被发送到网络中,当TCP在另一端接收到一个报文段之后,该报文段的数据就被放入该TCP连接的接收缓存中,应用程序从缓存中读取数据流,TCP连接的每一端都有各自的发送缓存和接收缓存。
从上面可以看出,TCP的连接包括:一台主机上的缓存、变量和与进程连接的套接字,以及另一台主机上的另一组缓存、变量和与进程连接的套接字。
因特网的网络服务层(IP服务)是不可靠的,IP不保证数据报的交付,不保证数据报的按序交付,也不保证数据报中数据的完整性。对于IP服务,数据报能够溢出路由器缓存而永远不能到达目的地,数据报也可能是乱序到达,而且数据报中的比特可能损坏(由0变为1或者相反),由于运输层是被IP数据报携带着在网络中传输的,所以运输层的报文段也会遇到这些问题。
TCP在IP不可靠的尽力而为的服务至上创建了一种可靠数据传输服务。TCP的可靠数据传输服务确保一个进程从其接收缓存中读出的数据流是无损坏,无间隔、非冗余和按序的数据流。
TCP提供可靠数据传输的步骤如下:我们先给出一个TCP发送方的高度简化描述,该发送方只用超时来恢复报文段的丢失;然后再给出一个更全面的描述,该描述中除了使用超时机制外,还是用冗余确认技术。接下来,我们假定数据仅向一个方向发送,即从主机A到主机B,且主机A在发送一个大文件。
下面有一个TCP发送方的高度简化的描述。我们看到TCP发送方有3个与发送和重传有关的主要事件:1.从上层应用程序接收数据;2.定时器超时和3.收到ACK。一旦第一个主要事件发生,TCP从应用程序接收数据,将数据封装在一个报文段中,并把该报文段交给IP。注意到每一个报文段都包含一个序号。这个序号就是该报文段第一个数据字节的字节流编号。而且如果定时器没有为某些其他报文段而运行,则当报文段被传给IP时,TCP就启动该定时器。(将定时器想象为与最早的未被确认的报文段相关联是有帮助的。)
TCP报文段结构如图
第二个主要事件是超时,TCP通过重传引起超时的报文段来响应超时事件。然后TCP重启定时器。
TCP处理发送方必须处理的第三个主要事件是一个来自接收方的确认字段(ACK)的到达(更确切的说是一个包含了有效ACK字段值得报文段)。当该事件发生时,TCP将ACK的值y与他的变量SendBase进行比较。TCP状态变量SendBase是最早未被确认的字节的序号。(因此SendBase-1是指接收方已正确按序接收到的数据的最后一个字节的序号。)TCP采用累积确认,所以y确认了字节编号在y之前的字节都收到。如果y>SendBase,则该ACK是在确认一个或多个先前未被确认的报文段。因此发送方更新它的SendBase变量;如果当前有未被确认的报文段,TCP还要重新启动定时器。