分类:
2010-12-22 19:11:06
TCP协议处于TCP/IP协议簇的传输层,它可以为网络提供有序可靠的分组数据交换服务。TCP在不可靠的分组传输网络上提供可靠的进程间通信机制,它具有分组丢失检测、自动重传、错误处理等保证可靠有序传输的功能。TCP不对高层协议的数据产生影响,它将来自高层的数据看成不间断的字节流,TCP为流中的每一个字节都分配一个序列号,在与对等的TCP交换报文时,TCP给这些段附加的控制信息包括该段中第一个字节的序列号以及该段中所有数据字节的个数,接收方的TCP就能够根据这些信息将不间断的数据流传送给自己的高层协议。
1.TCP报文段格式
TCP软件在两台计算机之间传输的数据单元称为报文段。报文段分为两个部分,前面是TCP头,后面是数据。TCP报文段格式如图3-11所示。
(1) 源端口
16位,表示发送方的端口号。因为TCP是一种进程通信协议,在同一个IP模块上可能有多个TCP应用程序在运行,仅仅使用IP地址无法唯一区别应用程序,所以同一主机上的不同应用程序使用端口区别。
(2) 目的端口
16位,表示接收方的端口号。
(3) 序列号
32位,表示该数据段中的第一个字节的序列号。如果TCP数据包中设置了同步信号(SYN),那么该值是初始序列号(initial sequence number, ISN),以后通信的第一个数据字节的序列号为ISN+1。序列号是数据流中字节的唯一性标识,因此如果有部分数据需要重新发送(比如没有接收到确认信息),那么从需要重新发送的第一个字节起的所有字节都要重新发送,并且要使用原来的序列号。
(4) 确认号
32位,如果设置了ACK则表示发送方期望下次接收到的数据段的起始编号。在连接建立后,ACK必须每次都发送并且要设置为本机已经接收到的最大数据段序列号加一。通信的另一方根据这个确认号来确定下次要发送的数据段。
(5) 数据偏移
4位,包含一个整数,指明报文段头的长度,单位是4字节。因为TCP报头中包含的任选项长度是可变的,所以TCP报头长度是不固定的。
(6) 控制位
6位,用来确定报文段的目的与内容。以下各位1表示有效,从左到右依次为:
URG:表示紧急指针数据段有效。
ACK:表示确认号数据段有效。
PSH:表示报文段请求一次推进操作,该标识要求TCP尽快将数据发送出去,而不要等待后续数据的到来。接收到带有PSH标志的数据段后要尽快处理。
RST:重置连接。本次连接被复位。
SYN:同步序列号,建立连接时使用。
FIN:发送者已经发送完数据,关闭连接时使用。
(7) 窗口
16位,表示发送者可以接收的数据字节数量。按网络字节顺序排列的整数。
(8) 检查和
16字节,TCP计算检查和和的方法与IP相同。但计算时必须在TCP数据帧前面加上一个伪数据头,伪数据头的格式如下:
其中,TCP的协议标识符为6,TCP报文长度指的是整个TCP报文的长度(不包括伪报头)。在计算时,把上面的伪数据头增加到TCP报文的前面,然后将检查和字节都设置为0,以2个字节为单位求和,有进位时将检查和加1,计算完毕后将结果按位取反。
(9)紧急指针
16位,当URG设置为1时该值有效。紧急指针指示该段数据中哪些数据是紧急的。虽然TCP是面向流的协议,但是有时候处在连接的一端的程序也需要立即发送带外数据,而不用等待连接的另一端上的程序消耗完数据流中正传输的数据。为了提供带外数据,TCP提供了紧急数据指针。当接收方发现紧急数据时,接收方的的TCP就通知与连接相关的应用程序进入紧急方式,在所有的紧急数据处理结束后,TCP才回到正常的运行方式。当发送紧急数据时,首先要设置URG,然后设置紧急指针,紧急指针指出窗口中紧急数据结束的位置,它的值是从序列号开始的数据段中的正偏移。
(10) 任选项
任选项用来处理其它各种情况,任选项长度是可变的,协议只要求它是以字节为单位的,因此有可能不是32位的整数倍,此时要在任选项后面添加填充项。目前使用的任选项有:(内容为16进制)
内容:00
表示任选项结束。
内容:01
可能出现在任选项域中的任何位置,为使任选项为32位的整数倍,可利用它来填充。
内容:02 04 <2字节表示的最大段长度>
设置TCP数据段的最大值。
2.TCP数据传输过程
TCP提供面向连接的可靠报文传输协议。因此,TCP传输数据前必须建立连接,在传输结束后必须断开连接,这些控制是通过TCP数据帧中的控制标志实现的。而TCP传输的可靠性和有序性是通过序列号和确认号来实现的,流量控制则通过窗口机制实现。TCP在两个端点之间建立等效于物理连接的逻辑连接,然后数据就可以沿着这个连接双向传送。连接的两边都必须对发送和接收的数据保存跟踪,以便能检测出数据流中的遗漏和重复。TCP中采用了字节序列机制,这种方法要求两边都对传送和接收数据的字节计数进行跟踪。当一定量的数据到达以后,接收者对字节计数进行确认,而不管它所表示的块数。
(1) TCP连接状态
TCP连接状态转换如图3-12所示。一个TCP连接过程分为两种,一种是处于被动状态的,即处于等待监听状态,等待对方的连接,一般称为服务器;另一种是处于主动连接状态,即主动发起连接的一方,一般称为客户端。图中方块内为连接状态,有向线代表了状态的转换,有向线旁边的标准中,虚线上为发生的事件,虚线下面为采取的动作。下面讨论建立连接和关闭连接的过程,在其中说明各状态的功能和转换方式。
TCP建立连接采用三次握手方式,这个连接过程一般由一个TCP初始化而由另一个TCP应答,当然也可以由双方同时发起。基本过程为:通信一方发送连接请求,另一方接收应答该请求并发送自己的连接请求,接收到对方的应答后握手完成。TCP连接的初始状态是CLOSED,此时TCP控制块不存在。此时如果采用被动打开,则应该创建传输控制块(Transmission Control Block, TCB)用来保存该连接需要的各种变量,然后进入LISTEN状态,此时TCP等待客户端的连接,当接收到客户端的同步请求数据帧时(以下简称SYN),发送SYN和ACK信号,连接进入SYN RECEIVED(同步接收完成状态)状态,然后等待对方的应答信号,接收到应答信号后连接建立完毕,进入ESTABLISHED状态。如果采用主动连接,在OPEN操作时,创建TCB并发送SYN数据帧,进入SYN SEND状态(SYN发送状态),在接收到SYN,ACK数据帧后连接建立完毕。图3-13是TCP典型连接的过程。
TCP的关闭过程是一个双向过程,即只有当通信双方都关闭连接时,连接才真正的关闭。某一方关闭连接意味着它将不再发送数据,但是它仍然可以接收数据。如果通信没有发生异常,都要使用正常的关闭连接过程,否则可能造成数据帧丢失等现象。关闭连接有以下三种情况:
1)本地主动关闭
当本地调用CLOSE操作时,TCP发送控制域为FIN的数据帧,进入FIN-WAIT-1状态,此时TCP将不再接收来自高层协议的数据。处于FIN-WAIT-1状态的TCP可以继续接收对方的数据并等待ACK标志,当接收到ACK后,TCP进入FIN-WAIT-2状态,TCP在这个状态里等待对方的FIN数据帧,当接收到FIN数据帧后,TCP应答ACK,然后等待超时时间后进入CLOSED状态,连接关闭。
2)接收到FIN数据帧
如果在通信过程中,如果从网络中接收到FIN标志,TCP模块发送ACK并通知上层协议连接关闭,此时上层协议应调用CLOSE操作,关闭本地TCP连接。
3)双方同时关闭
如果通信双方同时发送FIN启动关闭过程,则双方在接收到FIN数据帧后发送ACK,当接收到ACK后连接关闭。图3-14所示为一个典型的关闭过程。
(2)TCP数据通信
当连接建立完毕后,通信双方就可以通过交换数据段来传输数据。因为TCP是建立在不可靠的IP协议上的,所以,TCP报文有可能发生错误或丢失。在TCP中采用重传(Retransmission)来保证报文的无差错传输,由于使用了重新传输机制,所以可能接收到重复的报文,为了处理这种情况,TCP使用序列号和确认号检查数据。
序列号说明了当前数据块在数据流中的位置。如果第一个数据块的序列号是0,并且有20个字节长,那么下一个数据块的序列号就应该是20。确认号表示接收数据的总数。如果初始的序列号是0,并且有10个字节的数据需要确认,应答中的确认号就应该是10。因为TCP的数据传输是双向对称的,每一方对它自己的传输都保留一个序列号和一个确认号,并且每一方都对从对方节点接收来的序列号和确认号进行跟踪。
在TCP中,使用传输控制块(Transmission Control Block)来控制通信过程,该块保存了以下变量:
在发送数据时,发送方封装数据并增加SEND.NEXT,接收方接收到数据段后增加RECV.NEXT并给出应答ACK,发送方接收到应答后增加SEND.UNA。以上变量增加值是发送或接收的数据长度。在发送数据时,发送方在发送数据后会同时将数据放入重发队列,如果在超时时间内没有接收到ACK,则发送方将会从发送队列中重新发送数据,如果接收到应答,则将重发队列中的该部分数据删除。
接收到的ACK有效性判断使用如下不等式:
SEND.UNA 此时重发队列中的小于等于SEG.ACK的数据都已经得到确认,因此应当从队列中删除。在接收数据时要判断数据是否有效,判断不等式为: RECV.NEXT= RECV.NEXT= 对数据有效性的判断保证了数据流的可靠传输。在TCP中使用窗口进行流量控制。在每次发送数据时都会发送一个窗口值(见上文),该值指示了发送方可以接收的数据长度。如果接收到的数据长度超过窗口,那么超出的数据将被丢弃,这样将引起再次的重新传输,从而降低了通信效率。如果窗口值为0时,则通知发送方暂停发送,但是即使此时,接收方也必须保证能够接收一个字节的数据,因为发送方在检测到接收方的窗口为0后将定时发送数据,以检查接收是否可以开始接收数据,而此时的接收方在接收到数据后也要发送ACK进行应答并设置当前的窗口值。