考点五:TCP协议

考点五:TCP协议

1.TCP概述

UDP虽然效率高,但是UDP是不可靠的协议,面对一些需要可靠服务的应用,还需要让传输层提供可靠的协议。例如,我们去银行存钱,刚存进去2万元,当我们存钱的数据发给银行服务器时,数据丢了或数据重复发送了,出现这种情况肯定是不能接受的,数据丢了,你的钱没存上,你不愿意;数据重复发送了,你的钱多了,银行肯定不愿意。同时,有数据的破坏、丢包、重复及分片顺序混乱等问题。如果不能解决这些问题,就无从谈起可靠传输。

TCP是在不可靠的IP层之上实现的可靠的数据传输协议,它能够解决传输的可靠、有序、丢失和重复等问题,TCP通过检验和、序列号、确认应答、重发控制、连接管理及窗口控制等机制实现可靠性传输。该协议的特点如下:

(1)TCP是面向连接的传输层协议。

(2)每条TCP连接只能有两个端点(Socket),每条TCP连接都是点对点的。

(3)TCP提供可靠交付的服务,保证传送的数据无差错、不丢失、不重复且有序发送。

(4)TCP提供全双工通信。

(5)面向字节流。TCP传送的数据单元称为报文段。TCP编号是面向字节编号,而不是面向数据段编号。如图5-11所示,TCP协议对TCP数据段中的每个字节进行编号,其中每个TCP数据段的序号是本TCP数据段的第一个字节的编号,通过编号来保证数据的可靠传输。大家要注意,虽然TCP的数据形式称为TCP数据段,也是按照数据段进行传输的,但是其编号对TCP数据段中的每个字节进行编号。

图5-11 TCP面向字节流示意图

注意:

(1)TCP连接是虚连接而不是真正的物理连接。

(2)TCP对应用进程一次把多长的报文发送到TCP的缓存中是不关心的。

(3)TCP根据对方给出的窗口值和当前网络拥塞的程度来决定一个报文段应包含多少个字节(UDP 发送的报文长度是应用进程给出的)。

(4)TCP可把超长的数据块划分为短一些的再传送,也可等积累到足够多的字节后再构成报文段发送出去。

2.TCP报文段

TCP通过检验和、序列号、确认应答、重发控制、连接管理及窗口控制等机制实现可靠性传输,那么这些机制的具体实现依赖于相关的数据形态,其实是通过TCP的首部中进行体现的。一个TCP报文段分为TCP首部和TCP数据两部分。整个TCP段作为IP数据报的数据部分封装在IP数据报中,如图5-12所示,其首部的前20字节是固定的。TCP报文段的首部最短为20字节,后面有4N字节是根据需要而增加的选项,通常长度为4字节的整数倍。

图5-12 TCP报文段首部

TCP各字段意义如下:

(1)源端口和目的端口字段各占2字节,端口是传输层与应用层的服务接口。传输层的复用和分用功能都要通过端口才能实现,通过端口可以标记相同计算机中的不同进程。

(2)序号字段占4字节。TCP是面向字节流的(也就是说,TCP传送时是按照一个个字节来传送的),TCP连接中传送的数据流中的每个字节都要编上一个序号。序号字段的值指的是本报文段所发送的数据的第一个字节的序号。例如,一报文段的序号字段值是301,而携带的数据共有100字节,这就表明本报文段的数据的最后一个字节的序号是400,故下一个报文段的数据序号应从401开始。

(3)确认号字段占4字节,是期望收到对方的下一个报文段的数据的第一个字节的序号。若确认号为N,则表明1~N-1的所有数据都已正确收到。

例如,B正确收到了A发送过来的一个报文段,其序号字段是501,而数据长度是200字节(序号501~700),这表明B已收到了A发送的到序号700为止的数据。因此,B期望收到A的下一个数据序号是701,于是B在发送给A的确认报文段中把确认号置为701。

(4)数据偏移(首部长度)占4位,这里不是IP数据报分片的那个数据偏移,而是表示首部长度,它指出TCP报文段的数据起始处距离TCP报文段的起始处有多远。“数据偏移” 的单位是32位(以4字节为计算单位),因此当此字段的值为15时,达到TCP首部的最大长度字节。

(5)保留字段占6位,保留为今后使用,但目前应置0,该字段可以忽略不计。

(6)紧急位URG。当URG=1时,表明紧急指针字段有效,它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)。URG需要和紧急指针配套使用,数据从第一个字节到紧急指针所指字节就是紧急数据。

(7)确认位ACK。只有当ACK=1时,确认号字段才有效;当ACK=O时,确认号无效。TCP规定,在连接建立后,所有传送的报文段都必须把ACK置1。

(8)推送位PSH(Push)。TCP收到PSH=1的报文段,就尽快地交付接收应用进程,而不再等整个缓存都填满后再向上交付。

(9)复位RST(Reset)。当RST=1时,表明TCP连接中出现严重差错(如主机崩溃或其他原因),必须释放连接,然后重新建立传输连接。

(10)同步位SYN。当SYN=1时,表示这是一个连接请求或连接接收报文。

当SYN=1,ACK=O时,表明这是一个连接请求报文,对方若同意建立连接,则在响应报文中使用SYN=1,ACK=1,即SYN=1表示这是一个连接请求或连接接收报文。

(11)终止位FIN(Finish)用来释放一个连接。当FIN=1时,表明此报文段的发送方的数据已发送完毕,并要求释放传输连接。

(12)窗口字段占2字节。它规定现在允许对方发送的数据量,接收方的数据缓存空间是有限的,故用窗口值作为接收方让发送方设置其发送窗口的依据,单位为字节。例如,设确认号是701、窗口字段是1000,这表明从701号算起,发送此报文段的一方还有接收1000个字节数据(字节序号是701~1700)的接收缓存空间。

(13)校验和占2字节。校验和字段校验的范围包括首部和数据两部分。在计算校验和时,与UDP一样,要在TCP报文段的前面加上12字节的伪首部(只需将UDP伪首部的第4个字段,即协议字段的17改成6,其他的和UDP一样)。

(14)紧急指针字段占16位,指出在本报文段中紧急数据共有多少个字节(紧急数据放在本报文段数据的最前面)。

(15)选项字段长度可变。TCP最初只规定了一种选项,即最大报文段长度(Maximum Segment Size,MSS)。

(16)填充字段是为了使整个首部长度是4个字节的整数倍。

3.TCP连接建立

TCP是面向连接的协议,因此TCP在传输数据之前需要先建立连接,每个TCP连接都有3个阶段:建立连接、数据传送和释放连接。TCP连接的建立都是采用客户机-服务器方式。主动发起连接请求的应用进程称为客户机,被动等待连接的应用进程称为服务器。建立连接的过程中要解决以下3个问题:

(1)要使每方能够确知对方的存在。

(2)要允许双方协商一些参数(如最大报文段长度、最大窗口大小、服务质量等)。

(3)能够对传输实体资源(如缓存大小、连接表中的项目等)进行分配。

连接的建立经历以下3个步骤,通常称为“三次握手”,如图5-13所示。

图5-13 TCP连接建立过程图

(1)客户机A的TCP向服务器B发出连接请求报文段,其首部中的同步位SYN=1,选择序号seq=x,表明传送数据时的第一个数据字节的序号是x,这个特殊的报文段中不含应用层数据。在考试中,这个是已知的。

(2)服务器B的TCP收到连接请求报文段后,若同意,则发回确认。服务器B在确认报文段中应使SYN=1,ACK=1,其确认号ack=x+1,自己选择的序号seq=y。在考试中,这个是已知的,确认报文段同样不包含应用层数据。需要注意的是,ACK和ack的区别,ACK表示确认信号是有效的,而ack表示希望收到的下一个TCP数据段的第一个字节的标号。

(3)当客户机收到确认报文段后,还要向服务器给出确认。这个报文段的ACK=1, seq=x+l,确认号字段ack=y+1。

TCP连接建立以后,TCP提供全双工通信,通信双方的应用进程在任何时候都能发送数据(同时或者分时发送数据)。那么如何区分是第几次握手发送的数据呢?

第一次发送TCP连接请求是SYN=1,ACK=0。

第二次同意TCP连接请求是SYN=1,ACK=1。

第三次TCP连接确认是SYN=0,ACK=1。

在考试中,大家需要注意以下几点:

(1)第一次发送请求和第二次同意所携带的数据都是1字节,且所携带的数据不是应用层的数据,在计算应用层发送的数据量时,这两个字节不计算在内。

(2)因为TCP是一个全双工连接,所以发送方和接收方可以同时发送数据,那么发送方和接收方都需要对各自发送的数据进行编号,这两个编号是没有关系的。

(3)往往在发送第三次握手后,发送方会立即发送数据。

(4)大家需要注意,在每次握手时服务器和客户机的状态,这个也是最近几年爱考的点。

4.释放TCP连接

俗话说,天下没有不散的宴席,数据传输结束后,参与TCP连接的两个进程中的任何一个都能终止该连接,释放TCP连接的过程通常称为“四次挥手”。为什么需要四次挥手呢?

为了理解TCP连接是如何释放的,我们将TCP全双工的连接看成一对单工连接。每个单工连接的释放彼此独立。为了释放一个连接,任何一方都可以发送一个设置了FIN标志位的TCP段,这表示它已经没有数据要发送了。当FIN段被另一方确认后,这个方向上的连接就被关闭,不再发送任何数据。然而,另一个方向上或许还在继续着无限的数据流。当两个方向都关闭后,连接才算被彻底释放。通常情况下,释放一个连接需要4个TCP段,每个方向上一个FIN和一个ACK。

现在客户机A的应用进程先向其TCP发出释放连接报文段,并停止再发送数据,主动关闭TCP连接,如图5-14所示。

图5-14 用“四次挥手”释放TCP连接

(1)客户机打算关闭连接,就向其TCP发送一个释放连接报文段,主动关闭TCP连接,该报文段的FIN标志位被置为1,seq=u,u等于前面已经传送过的数据的最后一个字节的序号加1(FIN报文段即使不携带数据,也要消耗掉一个序号)。当发送FIN报文时,发送FIN的一端就不能再发送数据,也就是关闭了其中一条数据通路,但服务器还可以发送数据。

(2)服务器收到释放连接报文段后即发出确认,确认号是ack=u+1,而这个报文段自己的序号u等于前面已经发送过的数据的最后一个字节的序号加1。此时,从客户机到服务器这个方向的连接就释放了,TCP连接处于半关闭状态。

(3)若服务器已经没有要向客户机发送的数据,则通知TCP释放连接,此时其发出FIN=1的连接释放报文段。

(4)客户机收到释放连接报文段后必须发出确认,在确认报文段中,ACK字段被置为1,确认号ack=w+1,序号seq=u+1。此时TCP连接还没有被释放,必须经过时间等待计时器设置的时间2MSL(Maximun Segment Lifetime,报文最大生存时间)后,客户机才进入到连接关闭状态。为什么要等待2MSL时间呢?

第一,为了保证客户机发送的最后一个ACK报文段能够到达服务器。

第二,防止“已失效的连接请求报文段”出现在本连接中。

客户机在发送完最后一个ACK报文段后,再经过2MSL时间,就可以使本连接所持续的时间内所产生的所有报文段都从网络中消失。这样就可以使下一个新的连接中不会出现这种旧的连接请求报文段。

在考试中,需要特别提醒的是以下几点:

(1) 这四次挥手的字段标号其实是两次完全一样的操作,

第一次挥手是FIN=1,ACK=1。

第二次挥手是FIN=0,ACK=1。

第三次挥手是FIN=1,ACK=1。

第四次挥手是FIN=0,ACK=1。

(2)第一个ACK和第二个FIN有可能被组合在同一个段中,从而将所需段总数降低到3个。

(3)大家需要注意,在每次挥手时服务器和客户机的状态,这个也是最近几年爱考的点。

【政哥点拨】

1.TCP使用三次握手协议来建立连接,握手的第一个报文段是由码位字段的( )位被置为1来识别,表示请求连接。第一个报文段码字段的( )位和SYN位被置为1,指示对第一个报文的确认。当一个应用程序通知TCP数据已传送完毕时,TCP将单项地关闭这个程序,报文段码位字段的( )位均被置1,指示发送方已发送完数据。

A.SYN B.ACK C.PSH D.FIN

解析 A,B,D 本题考查三次握手的建立连接过程TCP首部SYN、ACK和FIN字段的变化及变化的含义。握手的第一个报文段令SYN=1,表示请求建立连接。应答该请求连接,回复一个ACK=1,并且把SYN置成1。

在释放连接时,FIN字段置为1。

2.主机甲向主机乙发送一个(SYN=1,seq=11220)TCP段,期望与主机乙建立TCP连接,若主机乙接收该连接请求,则主机乙向主机甲发送的正确的TCP段可能是( )。

A.(SYN=0,ACK=0,seq=11221,ack=11221)

B.(SYN=1,ACK=1,seq=11220,ack=11220)

C.(SYN=1,ACK=1,seq=11221,ack=11221)

D.(SYN=0,ACK=0,seq=11220,ack=11220)

解析 C 主机甲发送了一个(SYN=1,seq=11220)的TCP报文段,主机乙收到连接请求报文后,若同意连接,则向主机甲发送确认。在确认报文段中应把SYN位(SYN=1表示这是连接报文,SYN=0则表示不是连接报文,在TCP建立连接的3个过程中,SYN都为1)和ACK位都置1。其中,确认号是主机甲发送的TCP报文段的初始序号seq=11220+1,即ack=11221,表示期待主机甲发来的下一个报文的序号是11221。

与此同时,主机乙也要选择并消耗一个初始序号seq,该seq值由主机乙的TCP进程确定。本题中并没有告诉我们主机乙选择了哪个值作为TCP报文的序号。因此,我们不能从序列号中看出答案。B、C项我们不能通过主机乙回复的序列号来排除,只能通过ack=11221来确定。本题选择C项。

需要特别注意的是,本题取主机乙选取的序号seq=11221,但是主机甲和主机乙可分别选择不同的序号,而且这两个初始序号之间没有任何关系。

3.主机A基于TCP向主机B连续发送3个TCP报文段。第1个报文段的序号为90,第2个报文段的序号为120,第3个报文段的序号为150。

(1)第1个和第2个报文段中有多少数据?

(2)假设第2个报文段丢失而其他两个报文段到达主机B,那么在主机B发往主机A的确认报文中,确认号应该是多少?

解析 (1)TCP传送的数据流中的每个字节都是有一个编号的,而TCP报文段的序号为其数据部分第一个字节的编号。那么第1个报文段中的数据有120-90=30字节,第2个报文段中的数据有150-120=30字节。

(2)由于TCP使用累计确认的策略,当第2个报文段丢失后,第3个报文段就成了失序报文,B期望收到的下一个报文段是序号为120的报文段,因此确认号为120。

政哥应试提醒:TCP协议一直是考试的重点内容,尤其要注意TCP协议的特点,首部格式和连接建立以及连接释放的过程,最近几年连接建立和释放时客户机和服务器的状态也是命题热点。

难度系数:★★

牛刀小试

1.以下关于TCP的工作原理与过程的描述中,错误的是( )。

A.TCP连接建立过程需要经过“三次握手”的过程

B.当TCP传输连接建立之后,客户机与服务器的应用进程进行全双工的字节流传输

C.TCP传输连接的释放过程很复杂,只有客户机可以主动提出释放连接的请求

D.TCP连接的释放需要经过“四次挥手”的过程

2.一条TCP连接的建立,包括( )个步骤,它的释放过程包括( )个步骤。

A.2 B.3 C.4 D.5

3.有关TCP协议首部字段的意义,下列说法正确的是( )。

A.FIN=0,表明此报文段的发送端的数据已发送完毕,并要求释放连接

B.SYN=0,表明这是一个连接请求报文段,这时序号字段seq有效

C.ACK=0,表明这是一个连接请求报文段,这时ack有效

D.ack为确认序号,其值一般为对方发来的报文段序号(seq)+1

4.TCP报文段中确认序号指的是( )。

A.已经收到的最后一个数据序号 B.期望收到的第一个字节序号

C.出现错误的数据序号 D.请求重传的数据序号

5.如果主机1的进程以端口x和主机2端口y建立了一条TCP连接,这时如果希望再在这两个端口间建立一个TCP连接,那么会( )。

A.建立失败,不影响先建立连接的传输 B.建立成功,并且两个连接都可以正常传输

C.建立成功,先建立的连接被断开 D.建立失败,两个连接都被断开

牛刀小试解析

1.C 解析 本题阐述了TCP连接管理的过程,TCP连接建立需要“三次握手”,TCP的连接释放需要“四次挥手”,但是参与TCP连接的两个进程中的任何一个都能提出释放连接的请求。

2.B、C 解析 TCP建立连接经过“三次握手”。释放连接经过“四次挥手”。所以,答案是B和C项。

3.D 解析 本题考查TCP协议部分首部字段的含义。FIN=1,表明此报文段的发送端的数据已经发送完毕,并要求释放连接;FIN=0,表明无此含义。SYN=1表明这是一个连接请求报文段。ACK=1才是有效的(ACK=0表示无效),但是不代表连接请求报文。因此,A、B、C项都不正确。

ACK的确认序号一般是对方发来的报文段序号+1。所以,D项正确。

4.B 解析 本题考查TCP报文段的确认序号的含义。确认序号表示的是期待接收到的下一个报文段的数据部分的第一个字节的序号。

5.A 解析 一条连接使用它们的套接字来表示,因此(1,x)-(2,y)是在两个端口之间唯一可能的连接,而后建立的连接会被阻止,所以还有可能接收到数据。

大显身手

1.主机A向主机B连续发送了两个TCP报文段,其序号分别为70和100。试问:

(1)第1个报文段携带了多少个字节的数据?

(2)主机B收到第1个报文段后发回的确认中的确认号应当是多少?

(3)如果主机B收到第2个报文段后发回的确认中的确认号是180,试问:主机A发送的第2个报文段中的数据有多少个字节?

(4)如果主机A发送的第1个报文段丢失了,但第2个报文段到达了主机B。主机B在第2个报文段到达后向主机A发送确认。试问:这个确认号应为多少?

2.主机A和主机B建立TCP连接后,主机A准备向主机B发送的数据如表5-6所示,发送窗口的初始值为400。每个报文段的长度为100个字节,数据报文段序号的初始值为seq=301。请分析:

(1)主机A发送完seq=301的数据后未收到主机B发来的任何确认信息,请给出当前发送窗口的范围,并给出其中发送已确认、已发送未确认、可发送还未发送、不允许发送的字节范围。

(2)主机A发送完seq=601的数据后收到主机B发来的ACK=1,ack=501,win=300的报文,请给出当前发送窗口的范围,并给出其中发送已确认、已发送未确认、可发送还未发送、不允许发送的字节范围。

表5-6 主机A准备向主机B发送的数据

大显身手解析

1.解析 本题考查了TCP报文段的相关内容。

(1)主机A向主机B发送了序号分别为70和100的报文段,说明第1个报文段携带了100-70=30字节的数据。

(2)当主机B接收到了主机A发来的序号70,大小为30字节(表示该报文段的字节序号为70~99共30个序号)的报文段之后,如果报文段没有出错,确认号就应该是100。

(3)计算方法同(1),当主机B接收到了第2个报文,确认号为180,表示180号之前(100~179)的数据都接收到了。故而,第2个报文段应该携带的数据为180-100=80字节。

需要特别注意的是,100~179总共是80个序列号,不是79个,别粗心数错了。

(4)若主机A向主机B发送的第1个报文段丢失了,第2个报文段即使到达了B,但是B期待收到的下一个报文段的序列号仍然是第1个报文段的序号。故而主机B将请求主机A重发开始序号为70的报文段,确认号应为70。

2.解析 本题考查得很详细,要求同学们对TCP窗口数据的几种状态都有所了解。发送窗口中只可能存在3种状态的数据,即已发送而且已确认、已发送但未确认和可发送。

(1)发送窗口的初始值为400,主机A向主机B发送的报文段的初始序号为301。故而,发送窗口范围为301~700,已确认的字节范围为0。

因为A发送了100字节序号为301的报文段,但尚未收到主机B的确认,因此已发送未确认的字节范围为301~400。

可发送的字节为发送窗口内尚未发送的数据,本题中可发送的字节范围为401~700。

不允许发送的字节为落在滑动窗口之外的字节,本题中不允许发送的字节范围为701 以后。

(2)当主机A发送完seq=601的报文段后,收到了主机B发来的ack=501,win=300的确认,表明主机B期待收到的下一个报文序号是501。故而,主机A根据主机B发来的该确认,修改自己发送窗口的大小,发送窗口范围为501~800。

因为主机B的确认ack=501,表明序号为500及其以前的字节都收到了,即已确认的字节范围为301~500。

因为主机A发送完了seq=601,大小为100个字节的报文段,但是该段没有收到确认,故而已发送未确认的字节范围为501~700。

因为发送窗口的大小为300字节,还可发送的字节范围为701~800,所以不允许发送的字节范围为801以后。