2.9.1 TCP
1.TCP概述
TCP用于在不可靠的互联网络上提供可靠的端到端字节流传输服务。在一个TCP连接中,仅有两方进行彼此通信。TCP不提供广播或多播服务。
TCP把发送端实体要求发送的数据流分割成适当长度的数据段,然后传给IP层,再由IP层通过网络接口层将包传送给接收端主机。接收端主机接收到数据后,会将数据上传给指定的接收端实体。
TCP实体交换数据的基本单元(TPDU)称作“数据段”。每个数据段包含一个固定的20字节的头(还可加一个可选部分)和若干数据字节,其总长度由通信双方的最大段长(Maximum Segment Size,MSS)确定。当建立TCP连接时,双方互相声明自己的MSS,从中选择较小的MSS;或者直接选择默认的MSS(536字节)。MSS的选取应使得每个段封装后,其长度不超过IP分组的载荷能力(65535字节)及相应网络的MTU。超过网络的MTU的数据包在传输过程中会被分段。
2.TCP的特点
TCP为了保证不发生数据丢失,就对要传输的数据按字节标注序号。序号保证了传送到接收端实体的数据的按序接收。接收端实体对已成功收到的数据发回一个相应的确认(Acknowledgment,ACK)。如果发送端实体在规定的往返时延内未收到确认,那么对应的数据将会被重传。
TCP用一个校验和函数来检验数据是否有错误,在发送和接收时都要计算校验和。
TCP对字节流的内容不作任何解释,对字节流的解释由TCP连接双方的应用层解释。
TCP提供的是全双工连接。对一个应用程序而言,全双工连接包括了两个独立的、流向相反的数据流,而且这两个数据流之间不进行显式的交互。
由于TCP要提供可靠的、面向连接的字节流传输服务,因此,不可避免地增加了许多控制开销。这不仅使协议数据单元的首部增大很多,而且还要占用许多的处理机资源。
3.TCP协议的格式
TCP数据段封装在IP数据报中传输,通过数据段的交互来建立连接、传输数据。TCP数据段分为两部分,前面是头标,后面是数据。TCP头标的前20个字节格式是固定的,后面是可能的选项,数据长度最大为65535-20-20=65495字节,其中,第一个20指IP头标的最小长度,第二个20指TCP头标的最小长度。不带任何数据的数据段也是合法的,一般用于传输确认和控制信息。
每个字段的含义简介如下:
(1)源端口号(Source Port)。长16位,与IP数据报头中的源地址(Source Address)一起用来标识源主机的一个发送实体(应用进程)。
(2)目的端口号(Target Port)。长16位,与IP数据报头中的目的地址(Target Address)一起用来标识目的主机的一个接收实体(应用进程)。
(3)序列号(Sequence Number)。长32位,用来标识从TCP源端向TCP目的端发送的数据段的第一个字节的顺序号。如果将字节流看作是在两个应用程序间的单向流动,则TCP用顺序号对每个字节进行计数。序号是32位的无符号数,到达最大值(232-1)后又从0开始。主机在建立一个TCP连接时便会选择一个初始序列号(Initial Sequence Number,ISN),进行传输时,序列号便在ISN上不断增加。
(4)确认号(Acknowledgement Number)。长32位,用来标识接收方所期望收到的下一个顺序号,也同时表示接收方已正确接收到ACK之前的所有数据。只有当ACK标志的值为1时,确认号字段才有效。为提高效率,TCP可以累积确认,即在接收多个报文段后,一次确认。TCP为应用层提供全双工服务,这意味着数据能在两个方向上独立地进行传输。因此,连接的每一端必须保持每个方向上的传输数据序列号。
(5)TCP段头长度(Offset)。长4位,以4个字节为单位表示TCP头标的长度。因为TCP头标中“选项”字段的长度是可变的,因此,TCP段头长度实际上用于指明TCP数据段从哪里开始。4位的TCP段头长度最大值为15,因此,TCP最多有4×15=60(个)字节长的头标。由于头标中的固定部分占20个字节,因此TCP头标中“选项”字段的长度最大为60-20=40字节。
(6)保留位(Reserved)。长6位,以备将来TCP协议的扩展使用,目前必须置为0。
(7)控制位(Control)。由6个标志位构成,依次介绍如下:
①URG(Urgent)。为1表示紧急指针有效,为0则忽略紧急指针值。
②ACK(Acknowledgement)。为1表示确认号有效,为0表示报文中不包含确认信息,忽略确认号字段。
③PSH(Push)。为1表示是带有Push标志的数据,指示接收方应该尽快将这个报文段交给应用层而不用等待缓冲区装满。
④RST(Reset)。用于复位。由于主机崩溃或其他原因而出现错误的连接,即重建TCP连接。同时,它可以用于拒绝非法的报文段和拒绝连接请求。
⑤SYN(Synchronize)。同步序号,为1表示连接请求,用于建立连接和使顺序号同步。
⑥FIN(Final)。用于释放连接,为1表示发送方已经没有数据发送了,即关闭本方数据流。
(8)窗口大小(Window)。长16位,表示主机用于接收对方主机TCP数据的缓冲区的大小,即主机最希望收到的TCP段字节数。通告窗口大小是TCP实现拥塞控制的一种措施。窗口最大为216-1=65535字节。
(9)校验和(Checksum)。长16位,用于检验TCP数据段是否存在错误。校验的范围包括TCP头标、TCP数据以及伪头标。TCP的校验和计算方法与UDP类似。伪头标包括源主机和目标主机的32位IP地址、TCP的协议号以及TCP数据段(包括TCP头标)的长度,这些都是IP头标的字段。增加伪头部是为了校验和的计算,也可以检验TCP数据段是否正确递交。在TCP校验和计算中包括伪头部,这样有助于检测到错误递交的分组,但是这种方式是出于实际需要而做的折中,违反了协议分层的原则。
(10)紧急指针(Urgent Pointer)。长16位,当URG标志值为1时有效。当发送方有紧急数据需要传送时,TCP将紧急数据插入到TCP数据段的开头,并为紧急指针设置一个正的偏移量,将紧急指针定位到紧急数据的最后一个字节。这样,TCP接收端就能优先读取紧急数据,而又不影响原本数据的正常传输。设置紧急指针是发送端向另一端发送紧急数据的一种方式。
(11)选项。为可选字段,根据TCP连接的要求而变动。最常见的是最长报文大小。每个连接方通常都在为建立连接而设置SYN标志的那个段,也就是通信的第一个报文段中指明这个选项,它指明发送端所能接收的最大长度的报文段。
(12)填充项(Padding)。用于将整个TCP头标的长度填充为32的整数倍。填充字段各位都设置为0。
(13)数据。是可选的,在一个连接建立和一个连接终止时,双方交换的TCP段仅有TCP头标。如果一方没有数据要发送,也使用没有任何数据的TCP段来确认收到的数据。在处理超时的许多情况中,也会发送不带任何数据的TCP段。