首页 > 代码库 > TCP机制

TCP机制

1、面向连接的协议

面向连接的协议在两个对等端内部网之间直接建立逻辑连接。它通过跟踪数据的传送,并确认和跟踪序列号来确保成功到达接收方。确认是一种积极响应,表面数据已经到达。面向连接的对等端使用序列号跟踪确定发送的数据量和任何无序数据包。面向连接的协议中有超时机制,作用是当主机等待连接的时间太长时就认为是数据丢失。它还有重试机制,用来接收一定的重复次数重发丢失的数据。

面向连接的协议在数据包之间维持着状态信息,应用程序使用这些状态信息来进行额外的回话。这些记住的状态信息使协议能够提供可靠的提交。例如,发送者可以记住什么数据已经发送出去了但是还没有被确认,还可以记住它是什么时候发送出去的。如果在一定的时间间隔后还没有接到应答,发送者就重传该数据。接收者可以记住什么数据已经接收到了,而且可以丢弃重复的数据,如果数据包没有按顺序到达,那么接收者可以先保存,再等待逻辑上先于它的数据包到达。

典型的面向连接的协议包括3个阶段:

第一个阶段是双方建立连接;

第二个阶段是数据传输阶段;

第三个阶段是当双方已经结束了数据传输时,就关闭连接。

2、TCP(传输控制协议)

TCP为应用层提供了比UDP更多的功能,特别是差错回复、流控制和可靠性等功能。正如前面提到的那样,TCP的主要目的是在进程对之间提供可靠的逻辑链路,即连接服务。它不需要来自底层协议的可靠性,因此TCP必须保证自己的可靠性。TCP为应用提供的功能如下:

(1)流数据传输

对于应用程序,TCP在网络上传输连续性的字节流。应用程序不必把数据分成基本的数据块或者数据报,TCP通过以TCP分段的形式对数据进行分组,这些分段被传递到IP,然后传输到目的地。TCP本身确定了如何对数据进行分段,并且能够根据是否方便而转发数据。

有时,一个应用需要确信传递到TCP的所有数据已经真正传输到了目的地。为此,定义了一个推(PUSH)标志。它将把仍然在存储器中的所有剩余的TCP分段推入目的主机。正常的关闭连接功能也把数据推入目的端。

(2)可靠性

TCP为传输的每个字节分配了一个序号,并期望从接收端的TCP得到一个肯定的确认(ACK)。如果在一个超时的间隔内没有收到一个ACK,则数据会被重传。因为数据按块(TCP报文段)的形式传输,所有TCP报文段中的每一个数据字节的序列号被发送到目的主机。

当报文无序到达时,接收端TCP使用序列号来重排TCP报文段,并删除重复发送的报文段。

(3)流控

接收端TCP在把一个ACK发回发送方时,也向发送方指明除了最后一次接收到的TCP段外能够接收的字节数,从而不会在它的内部缓冲区中出现超出和溢出。在ACK中,用能够接收的不会出错的最大序列号进行发送,这种机制也称为窗口机制。

(4)多路复用

通过使用端口来实现。不同的数据流必须在单个数据单元中传输。为了能够传输这样的数据单元,所有的数据流必须联合成一个单一的数据体后再在网络上传输。这个过程就被称为多路复用。

(5)逻辑连接

上述可靠性和流控机制要求TCP初始化每种数据流,并为它们维护某种状态信息。这种状态的合并,包括套接字、序列号和窗口大小,称为一个逻辑连接。每个连接由发送进程和接收进程使用的套接字对所标识。

(6)全双工

TCP提供了双向并发数据流机制。

3、TCP窗口原则

一个简单的传输协议可以使用的原则是:发送一个报文,然后等待接收方的确认,收到确认后再发出下一个报文。如果在一个特定的时间间隔内没有接收到ACK,则重传这个报文。虽然这种机制保证了可靠性,但是只利用了一部分可用的带宽。现在,发送方把要传输的报文分组,并遵循如下的规则:

(1)在一个时间窗内,发送方能够在没有接收到一个ACK的情况下发送所有报文,但是必须为每个报文启动一个超时计时器。

(2)接收方必须确定接收到的每个报文,指示最后一个正确收到的报文的序列号。

(3)发送方在接收到每个ACK时滑动窗口。

4、TCP连接的建立

1)、 建立连接




    在源主机想和目的主机通信时,目的主机必须同意,否则TCP连接无法建立。为了建立一个TCP连接,两个系统需要同步其初始TCP序号ISN。序号用于跟踪通信顺序并确保多个包传输时没有丢失。初始序号是TCP连接建立时的起始编号。为了确保TCP连接的成功建立,TCP采用了一种称为三次握手的方式,三次握手方式使得“序号/确认号”系统能够正常工作,从而使它们的序号达成同步。如果三次握手成功,则连接建立成功,可以开始传送数据信息。 

  其三次握手分别为:
  第一步:源主机A的TCP向主机B发出连接请求报文段,其首部中的SYN(同步)标志位应置为1,表示想与目标主机B进行通信,并发送一个同步序列号X(例:SEQ=100)进行同步,表明在后面传送数据时的第一个数据字节的序号是X+1(即101)。SYN同步报文会指明客户端使用的端口以及TCP连接的初始序号。
  第二步:目标主机B的TCP收到连接请求报文段后,如同意,则发回确认。在确认报中应将ACK位和SYN位置1,表示客户端的请求被接受。确认号应为X+1(图中为101),同时也为自己选择一个序号Y。
  第三步:源主机A的TCP收到目标主机B的确认后要向目标主机B给出确认,其ACK置1,确认号为Y+1,而自己的序号为X+1。TCP的标准规定,SYN置1的报文段要消耗掉一个序号。
  运行客户进程的源主机A的TCP通知上层应用进程,连接已经建立。当源主机A向目标主机B发送第一个数据报文段时,其序号仍为X+1,因为前一个确认报文段并不消耗序号。
  当运行服务进程的目标主机B的TCP收到源主机A的确认后,也通知其上层应用进程,连接已经建立。至此建立了一个全双工的连接。

(2)、 传送数据

  位于TCP/IP分层模型的较上层的应用程序传输数据流给TCP。TCP接收到字节流并且把它们分解成段。假如数据流不能被分成一段,那么每一个其它段都被分给一个序列号。在目的主机端.这个序列号用来把接收到的段重新排序成原来的数据流。
  如图给出了两台主机在成功建立连接后传输数据的示例。



    (1) 主机A使用滑动窗口发送全部的四个段到主机B。这是第一步。不幸的是,只有段l03、105和106成功地到达了主机B(参看②)。 

  (2) 因为段103和104是连续的,所以主机B返回一个确认给主机A,通知主机A它只成功地接收到了第103段,在它的确认中主机B使用它期待得到的下一个序列号作为确认(参看③通过给出序列号104)。
  (3) 主机A接到主机B的报文后,重新发送段104、105和106(参看④)。虽然主机B已经成功地收到了段105和106,但是根据协议规定,也必须重新发送。
  (4) 当主机2成功地收到这些段以后.主机B返回一个确认给主机A(参看⑥),并根据序列号把它们重组成原来的数流。把它传输到高层应用程序。

(3)、终止TCP连接

    一个TCP连接建立之后,即可发送数据,一旦数据发送结束,就需要关闭连接。由于TCP连接是一个全双工的数据通道,一个连接的关闭必须由通信双方共同完成。当通信的一方没有数据需要发送给对方时,可以使用FIN段向对方发送关闭连接请求。这时,它虽然不再发送数据,但并不排斥在这个连接上继续接收数据。只有当通信的对方也递交了关闭连接的请求后,这个TCP连接才会完全关闭。
  在关闭连接时,既可以由一方发起而另一方响应,也可以双方同时发起。无论怎样,收到关闭连接请求的一方必须使用ACK段给予确认。实际上,TCP连接的关闭过程是一个四次握手的过程,这由TCP的半关闭造成的。
  在关闭连接之前,为了确保数据正确传递完毕,需要采用“四次握手”的方式来关闭连接,如图所示。
  其四次握手分别为:
  第一步:源主机A的应用进程先向其TCP发出连接释放请求,并且不再发送数据。TCP通知对方要释放从A到B这个方向的连接,将发往主机B的TCP报文段首部的终止比特FIN置1,其序号X等于前面已传送过的数据的最后一个字节的序号加1。



    第二步:目标主机B的TCP收到释放连接通知后即发出确认,其序号为Y,确认号为X+1,同时通知高层应用进程,如图中的箭头①。这样,从A到B的连接就释放了,连接处于半关闭状态,相当于主机A向主机B说:“我已经没有数据要发送了。但如果还发送数据,我仍接收。”此后,主机B不再接收主机A发来的数据。但若主机B还有一些数据要发送主机A,则可以继续发送。主机A只要正确收到数据,仍应向主机B发送确认。 

  第三步:若主机B不再向主机A发送数据,其应用进程就通知TCP释放连接,如图中的箭头②。主机B发出的连接释放报文段必须将终止比特FIN和确认比特ACK置1,并使其序号仍为Y,但还必须重复上次已发送过的ACK=X+1。

    第四步:主机A必须对此发出确认,将ACK置1,ACK=Y+1,而自己的序号是X+1。这样才把从B到A的反方向的连接释放掉。主机A的TCP再向其应用进程报告,整个连接已经全部释放。