由于互联网各个组成网络的特性有很大差异,要在网络层提供面向连接服务就需要很复杂的互通能力和信令协议,为了简化网络互联实现,Internet在网络层只提供简单的无连接服务,而将保证可靠传送的任务交给了运输层的TCP。TCP的设计目的就是动态适配互联网络的变化特性,在不可靠的网络上提供一条可靠的端到端的传输通道。这条通道就是TCP连接。
TCP连接是点到点的双向连接,对应源主机和目的主机应用进程之间的逻辑联系。它不支持多播和广播。任一方发起建立连接后,双方都可以在此连接上向对端发送信息。信息发送为双工方式,也就是说,双向数据流发送互相独立,在发送数据的报文中也可捎带传送控制信息,以提高带宽利用率。
作为一个点到点连接,TCP连接应该由二端的端点地址对来标识:{端点1地址,端点2地址}用分层协议结构中的服务接人点(SAP)概念来描述,端点地址应为:(主机地址,NSAP,TSAP) 其中,主机地址就是IP地址,NSAP为网络层SAP,也就是TCP协议,已在IP数据报头部标明,TSAP指明是哪一个应用进程,在TCP中将其称为端口(Port),因此,一个TCP连接的标识应为:(IP地址1,端口l),(IP地址2,端口2),每个端口可用一个整数表示,称为端口号,TCP协议规定端口号可占16比特。原则上,一个应用进程和端口号没有固定的对应关系。当一个进程创建后需要和远端建立联系或准备接受远端的联系请求时,该进程可通过系统调用请求操作系统为其随机分配一个端口号,其后即用该端口号代表该进程。当通信关系结束时,就将该端口号归还系统。这称为端口动态绑定技术。但随之而来的一个问题就是源主机如何才能获知目的进程的端口号。
为了解决这一问题,ARPANET专门提出了一个初始连接协议。考虑到计算机网络应用采用的基本上都是客户机/服务器工作模式,之所以要建立TCP连接一般是客户机需要从服务器获得某项信息,进行某项运算或共享某项资源,因此TCP连接建立也采用客户机/服务器模式,发起连接请求的主机叫客户,接受连接请求的则是服务器。初始连接协议要求所有服务器主机装备一个后台进程,叫进程服务器。该进程随系统一起启动,常驻内存,并和一个固定的端口号绑定(静态绑定),该端口号为互联网中的公开号码,称为“公认端口”(WE1l-knownport)。客户按服务器的IP地址和此公认端口发出连接请求,由进程服务器负责建立一条临时连接。然后,客户通过此临时连接向进程服务器发送一个报文,告之它希望得到的服务,进程服务器负责创建一个运行指定服务程序的进程,并给它分配一个端口号。最后,进程服务器向客户告之该端口号,并释放临时连接。其后,客户即可通过该端口号和指定服务程序建立连接,获得所需要的服务。
初始连接协议对于那些可以按需随时创建的服务进程是有效的,但是有许多情况,服务进程必须独立于进程服务器存在,例如文件服务器必须在专门的硬件上运行,不能在某客户需要用到时才创建。为此,又提出了一种名字服务器方案。该服务器独立设置,也与一个公认端口绑定。每当一个新的服务进程创建时,必须向名字服务器登记,告之其端口号。客户要和该服务进程建立联系时就向名字服务器查询,获得该进程的端点地址。名字服务器的作用犹如电话网中的查号台,因此也称为目录服务器。
TCP协议结合静态绑定和动态绑定技术,将端口分为两类,一类为公认端口,固定分配给一些标准的服务进程,另一类为自由端口,可由操作系统自行分配。客户进程要与远程服务进程通信之前,先申请一个自由端口,然后根据公认端口和远程服务器建立联系。不常用的服务进程可通过名字服务器建立联系。
TCP规定小于256的端口号为公认端口号,例如,FIP为21,TE1NEr为23等。公认端口分配表可见RFC1700。
从协议角度说,端口是运输层的服务接人点;从软件结构来说,端口对应为应用程序和通信程序之间的接口,包括一定容量的数据缓冲区和数据结构,端口操作类似于一般的1/0操作,可以用读写原语对其询问。需要指出的是,TCP/IP并没有对应用程序接口标准化。实际中,应用最为广泛的是UNIX关于TCP的插口(SOCKEf)原语。它包括8个原语,如表2.3所示。

服务器侧启动后,先调用SOCKEf原语,请求在TCP实体中分配缓冲区空间,执行后返回一个文件描述符,其方式和open调用相同;然后再用BIND原语绑定端口号,多为公认端口号;接着调用USTEN,分配队列,以便处理数个客户同时请求建立连接的情况;最后调用ACCF.Pf,使进程挂起,等待连接请求到来。当客户发来连接请求报文时,TCP实体创建一个和原先插口特性相同的新的插口,并返回一个文件描述符,服务器创建一个进程或线程来处理该新插口上的连接,然后退回等待原接口上的下一个连接。
客户侧首先也要调用SOCKEf原语,由此获得端口号,由于客户端口号为自由分配,无需BIND原语;然后调用CONNECT原语,启动连接过程,客户进程挂起;待收到服务器返回的证实响应,进程恢复,连接建立成功。其后双方可采用SEND和RECEIVE原语收发数据。连接释放为对称过程。当两端执行CWSE原语后,连接即释放。
由上述过程可知,同一服务进程可以和多个连接相连,对应为多个客户同时访问该服务进程。这和TCP连接是点到点连接并不矛盾,因为连接另一端的端点地址各不相同。另外,一个TCP连接两端的端口号一般是不相同的,也就是说两端通信的进程是不对称的,这是源于TCP连接的客户/服务器模式。这点和电信网中的信令有很大的不同,后者工作于对等模式。TCP连接工作于对等模式的情况很少,典型例子是路由协议。
TCP连接的另一个特点是,它传送的是字节流,而不是报文流。报文(message)必然具有边界,但是TCP对边界和内容字节不加区别。应用进程将报文按顺序写入TCP的缓存区,TCP可以立即将其发出,也可以将其缓存后和后续数据合在一起发送,以提高传输资源的带宽利用率,究竟如何发送,完全由TCP决定,其考虑的主要因素是传输效率。
TCP一次发送的字节块称之为段(Segment),段和报文边界没有对应关系。接收方TCP并不知道段字节的含义,它关心的只是保证无差错地传送每个字节,而将报文重组的任务交给应用进程去完成。类似于点到点数据链路协议,它只负责比特流的可靠传送,并不关心比特流的含义。段的最大尺寸(包括段头)受限于两个因素,一是IP净荷上限65535个字节,二是每个路径网络的MTU。一般MTU为儿于个字节,它们限定了段的大小。如果中途遇到某个网络的MTU小十段长,则由路由器负责分片,将其拆成两个或更多个段。
通常TCP对小报文要暂存后再发送,但是有的时候应用进程要求立即发送。例如,用户登录于某远程主机,键入一行命令回车后必须立即发往远端,以免和下一命令行混淆。为了强制数据即时输出,应用进程可在报文后加上PUSH(推出)标志,告诉TCP不要延迟对此报文的发送。
此外,应用进程还可利用URGENT(紧急)标志发送紧急数据。例如,用户敲击DE1或CIBL-C键终止远程主机业已开始的某项计算,此时发送应用进程在数据流中置入控制信息,加上紧急标志后送给TCP,TCP立即将其发出。接收方TCP收到紧急数据后,立即中断应用进程(在UNIX中就是给出信号),后者停止当前工作,读入数据流。紧急数据的结尾有标志,但其开始没有标志,需由应用进程自行判定。紧急数据的发送不受流量控制的限制。
1. TCP协议过程
TCP协议主要包括3个过程
(1)连接控制
主要解决连接如何可靠地建立和释放。这一问题看来简单,但是由于控制报文本身可能丢失;丢失后可能重发;尤其是报文可能并未丢失,只是暂存在中途网络而造成源端的时延重发,重发报文和经长时延的原来报文都到达接收端,如果处理不当就会造成重复的二次连接建立,在某些情况下会造成严重的后果。
例如,某用户和银行建立连接,然后发送数据报文通知银行将某笔款项转至另一户头,接着就释放连接。如果网络严重拥塞,每个报文都被暂存在中间网络,造成时延重发,重发后的报文又被暂存。过r一段时间后,这些报文相继弹出送往银行。银行会误认为这是两次独立的请求,于是将两笔款项重复地转至该户头。
类似地,在连接释放时,如果采用简单的释放—释放证实的一问一答方式,若释放证实报文丢失,就可能造成证实方已关闭连接,发起释放力迟迟未断连,甚至可能继续送数据而造成数据丢失。
经过对许多方案的分析比较,TCP协议采用了三次握手的建连和断迕力法,具体过程在下一小节给出。
(2)传输控制
主要解决端到端数据的尤差错传送,这里尤差错指的是尤丢失、尤错序、尤重复。传输控制的实现基于两种传送机制:确认传送和超时重传。
确认传送最简单的方法就是发方每发一段,就要停下来等待对方的确认;待收到确认后再发下一段。这种方式的缺点是传送效率太低。TCP协议采用的是滑动窗口方式。滑动窗口的大小W表示发送方允许发送的未被确认的最大数目的字节数。发送方可用3个指针来控制数据的发送,如图2.31所示。指针l指示尚未确认的第1个字节,即钳口下沿;指针2指示密口上沿,它与指针1之间的距离就是窗口大小;指针3指示下-个要发送的字节。当收到新的确认后,指针1和2向右移动,即窗口向前滑动。

超时重传是-种简单的差错校正方法CTCP不采用HDLC中常用的后向证实、请求重发机制,因为IP网络的传送是不可靠的,重发请求报文也易丢失CTCP每发送个段后就启动-个定时器,若超时仍未收到对于该段的确认,就自动重发。超时重传机制的关键是确定合理的定时器值。如果太大,则等待确认的时间太长;如果太小,则网络中重传报文将太多。重传要求TCP数据发出后不能丢弃,必须暂存至收到确认为止。
(3)流量控制
也就是拥塞控制,流量控制的实现也是基于滑动窗口机制。和传输控制不同的是,其窗口大小受网络拥塞情况控制,而传输控制窗口大小决定于接收方TCP缓冲区可用空间的大小。
2. TCP段的头部结构

TCP段的头部结构如图2.32所示。其长度也是4字节的整数倍,包括20字节的固定部分和长度不定的任选部分。由于IP数据报的最大长度是65535字节,因此TCP段的数据部分最大长度为65535-20-20=65495字节,其中第1个20字节是IP报头。TCP段也可能不含任何数据,为确认或控制报文。各字段的意义为:
(1)源端口和目的端口:和IP报头中的源和目的IP地址一起,构成连接标识。
(2)序号和确认号:序号表示本段数据在TCP发送流中的位置,即是从流中第几个字节开始的数据段。确认号是告诉对端下一期望收到的字节的序号。注意:TCP确认的对象是字节,而不是段,因为段在传输过程中可能会被分析,具有端到端意义的只能是字节。字节号的范围为0-232-1,若某主机按全速率在IOMbit/sLAN上发送数据,也要经过1个小时才会使序号返回原值。实际上序号返回时间远大于1个小时。
(3)TCP头部长度:长度单位为4个字节。该字段占4个比特。实际上指示的就是数据部分在段中的起始位置。
(4))标志码:共定义了6个标志比特。
·URG:紧急比特。该位置l表示头部的紧急指针启用。
·ACK:确认比特。该位置l表示头部的确认号有效;置0表示本段未捎带确认信息,因此接收方应忽略段中的确认号字段。
·PSH:推出比特。置1表示请求接收方收到本段数据后立即递交应用进程,不要缓存。
·RST:复位比特。该位置1表示连接复位,接收方收到此指示后立即退出连接,停止传输,释放缓冲区等资源。它用于由于主机崩溃或其它原因要求的连接异常中断。该比特也可用于拒绝连接建立,或拒绝不合法段。
·SYN:同步比特。该位和ACK位配合用于连接建立。
·FIN:结束比特。该位置1表示已无数据发送,请求释放连接。
(5))窗口大小:指示对方从确认的字节开始还可发送多少字节。窗口大小为零指示对方暂停发送数据。其后恢复时,再发送一个段,窗口大小非零,证实号和本段相同。
(6))校验和:为段头部、数据部分和图2.33所示伪头部的校验和。校验和的计算方法和IP报相同。因为计算是对16比特半字进行的,所以如果数据部分的字节数为奇数,计算时需要填充一个全零字节。伪头部包括源和目的IP地址、TCP协议编号(6)和TCP段的字节数(含头部)。将伪头部纳入校验和的目的是进一步提高TCP连接的可靠性,然而从理论上说,它违背了协议分层结构原理。

图2.33伪头部结构
(7))紧急指针:URG比特置1时有效。指示紧急数据在报文段中的结束位置,其值为相对于当前序号的偏移字节数。
(8)任选部分:已定义的任选部分字段有:
.最大TCP净荷:向对方指明本端能够接收的最大TCP净荷数,供连接建立时协商用。最后建立的连接的最大TCP净荷取两方公告值中的较小值。如果未用此任选字段,则取缺省值536个字节。所有Internet主机要求至少能接收536+20=556字节的TCP段。
窗口比例尺:由于窗口大小字段占16比特,因此窗口大小最多为64K字节。对于高带宽链路来说,有时尚嫌此值过小。增设比例尺字段,可使窗口字段参数最多左移16比特,达232字节。
.选择性重传:此字段允许TCP发送否定证实,指明需要对方重传哪一段或哪几段,以取代退回n顺序重传方式,减少重传报文。

图2.34TCP连接建立过程
图中,粗实线表示服务器的正常转移路径,细实线表示客户机的正常转移路径,虚线表示异常路径。每条状态转移线旁标有E/A标记,E表示转移触发事件,A表示转移时执行的动作。
3. 连接建立
TCP连接建立的三次握手过程如图2.34所示。A、B分别为客户和服务器,B执行LISTEN和ACCEPf原语后,等待连接请求的到来。
A执行CONNECT原语后,发出TCP段,其中SYN=I.ACK=0,初始序号设为X,段中可带用户数据(如口令)。该段到达B后,B的TCP实体查验是否有进程在该段指明的日的端口守听,如没有,就返回一个段,置RST=1;如有就将该段送交守听进程,该进程可决定接受还是拒绝该连接请求。如接受,则回送确认段,置序号=Y确,认号=X+1 A收到此段后,也返回一个确认段,置序号=X+1,确认号=Y+1义至此,连接建立成功。

图2.34TCP连接建立过程
上述三次握手过程可以有效地处理各种异常情况。现以上图2.35为例进行说明。图(a)为A、B双方同时发起连接请求的碰撞情况。双方都按照正常过程发送确认段,对于任}方来说都已完成三次握手过秷。表面上看来建立了两条连接,但由图2.34TCP连接建立过和于它们的端点对相同,因此在插口表项中只占有-个表项,也就是说只建立起一条连接。

图(b)为一条连接建立、通信并释放后,延迟重复的连接请求又到达B,B虽然回送确认段,但A发现它并未发送关于该连接的请求,于是就回送拒绝段(RST=l),不可能错误地再次建立此连接。
图(c)为延迟重复的连接请求和数据段相继到达B。B收到重复的数据段时,因连接尚未建立,因此不会接受此数据。其后收到A发回的拒绝段,就终止连接的建立c另外需要注意飞点,连接请求中的初始序号不能取为0。其原因是当主机崩溃后重新恢复时,如果以同样的初始序号重新进行连接建立,对方就会认为原有的连接依然存在,而不理会此次连接请求。一般采用基于时钟的方法随机选择初始序号。
4. 连接释放
连接释放也采用三次握手过程 ,如图2.36所示:

连接释放可由任一方发起,释放过程将连接视作两条独立的单工连接。如A方发出释放请求(FIN=l),并收到B方对该释放段的确认以后,则A->B的连接关闭,即A---->B停止发送数据,但8>A仍可发送数据。要关闭B---->A的连接需反向执行同样的操作。在图2.36中,B收到A发来的释放请求后,要经过一定时间才能发出至A的释放请求,因为B需通知应用进程并获得关闭连接的命令,其间可能涉及人机交互操作。为了防止超时重传,B应立即向A返回释放确认,以先行关闭A.-B的连接。
如果发出释放请求的一方在2倍分组最大生存时间内未收到确认,则自行释放该连接。其后,对端将检测到对方进程已不在通信状态,于是也将超时释放连接。
5. 连接管理状态转移图
上述兀P连接管理过程可由图2.37所示的状态转移图完整地描述:

图中,粗实线表示服务器的正常转移路径,细实线表示客户机的正常转移路径,虚线表示异常路径。每条状态转移线旁标有E/A标记,E表示转移触发事件,A表示转移时执行的动作。
现以一条正常路径予以简要说明。服务器调用LISTEN原语后从“关闭"状态进入“守听”状态。此时客户机调用CONNECT原语后,发出连接请求(SYN=l),进入“同步已发送”状态,服务器收到此请求后,返送确认(SYN+ACK)段后进入“同步已接收”状态。客户机收到此确认后向服务器回送确认,进入“连接已建“状态,服务器收到客户机发来的确认后也进入“连接已建“状态。
随后,客户机调用CWSE原语,发出释放请求(FIN),主动关闭连接,进入“关闭等待1"状态。服务器收到此释放请求立即返回确认(ACK),进入“关闭等待”状态Q客户机收到确认后进入“关闭等待2"状态 其后,服务器调用CLOSE原语,发出释放请求,进入“最终确认"状态。客户机收到此请求后,立即发回确认,进入“定时等待"状态,以作资源释放等善后工作,定时器时间到就回到“关闭"状态。服务器收到客户机发回的确认后,也回到“关闭"状态。