文章目录
- TCP首部格式
- 源端口号(Source Port)
- 目标端口号(Destination Port)
- 序列号(Sequence Number)
- 确认应答号(Acknowledgement Number)
- 数据偏移(Data Offset)
- 保留(Reserved)
- 控制位(Control Flag)
- 窗口大小(Window Size)
- 校验和(Checksum)
- 紧急指针(Urgent Pointer)
- 选项(Options)
TCP首部格式
TCP中没有表示包长度和数据长度的字段。可由IP层获知TCP的包长由TCP的包长可知数据的长度。
源端口号(Source Port)
表示发送端端口号,字段长16位。
目标端口号(Destination Port)
表示接收端端口号,字段长度16位。
序列号(Sequence Number)
字段长32位。序列号(有时也叫序号)是指发送数据的位置。每发送一次数据,就累加一次该数据字节数的大小。
序列号不会从0或1开始,而是在建立连接时由计算机生成的随机数作为其初始值,通过SYN包传给接收端主机。然后再将每转发过去的字节数累加到初始值上表示数据的位置。此外,在建立连接和断开连接时发送的SYN包和FIN包虽然并不携带数据,但是也会作为一个字节增加对应的序列号。
确认应答号(Acknowledgement Number)
确认应答号字段长度32位。是指下一次应该收到的数据的序列号。实际上,它是指已收到确认应答号减一为止的数据。发送端收到这个确认应答以后可以认为在这个序号以前的数据都已经被正常接收。
数据偏移(Data Offset)
该字段表示TCP所传输的数据部分应该从TCP包的哪个位开始计算,当然也可以把它看作TCP首部的长度。该字段长4位,单位为4字节(即32位)。不包括选项字段的话,TCP的首部为20字节长,因此数据偏移字段可以设置为5。反之,如果该字段的值为5,那说明从TCP包的最一开始到20字节为止都是TCP首部,余下的部分为TCP数据。
保留(Reserved)
该字段主要是为了以后扩展时使用,其长度为4位。一般设置为0,但即使收到的包在该字段不为0,此包也不会被丢弃(保留字段的第4位(如下图中的第7位)用于实验目的,相当于NS(Nonce Sum)标志位。) 。
控制位(Control Flag)
字段长为8位,每一位从左至右分别为CWR、ECE、URG、ACK、PSH、RST、SYN、FIN。这些控制标志也叫做控制位。当它们对应位上的值为1时,具体含义如图所示。
- CWR(Congestion Window Reduced)
CWR标志(关于CWR标志的设定请参考5.8.4节。) 与后面的ECE标志都用于IP首部的ECN字段。ECE标志为1时,则通知对方已将拥塞窗口缩小。
- ECE(ECN-Echo)
ECE标志表示ECN-Echo。置为1会通知通信对方,从对方到这边的网络有拥塞。在收到数据包的IP首部中ECN为1时将TCP首部中的ECE设置为1。
- URG(Urgent Flag)
该位为1时,表示包中有需要紧急处理的数据。对于需要紧急处理的数据,会在后面的紧急指针中再进行解释。
- ACK(Acknowledgement Flag)
该位为1时,确认应答的字段变为有效。TCP规定除了最初建立连接时的SYN包之外该位必须设置为1。
- PSH(Push Flag)
该位为1时,表示需要将受到的数据立刻传给上层应用协议。PSH为0时,则不需要立即传而是先进行缓存。
- RST(Reset Flag)
该位为1时表示TCP连接中出现异常必须强制断开连接。例如,一个没有被使用的端口即使发来连接请求,也无法进行通信。此时就可以返回一个RST设置为1的包。此外,程序宕掉或切断电源等原因导致主机重启的情况下,由于所有的连接信息将全部被初始化,所以原有的TCP通信也将不能继续进行。这种情况下,如果通信对方发送一个设置为1的RST包,就会使通信强制断开连接。
- SYN(Synchronize Flag)
用于建立连接。SYN为1表示希望建立连接,并在其序列号的字段进行序列号初始值的设定(Synchronize本身有同步的意思。也就意味着建立连接的双方,序列号和确认应答号要保持同步。) 。
- FIN(Fin Flag)
该位为1时,表示今后不会再有数据发送,希望断开连接。当通信结束希望断开连接时,通信双方的主机之间就可以相互交换FIN位置为1的TCP段。每个主机又对对方的FIN包进行确认应答以后就可以断开连接。不过,主机收到FIN设置为1的TCP段以后不必马上回复一个FIN包,而是可以等到缓冲区中的所有数据都因已成功发送而被自动删除之后再发。
窗口大小(Window Size)
该字段长为16位。用于通知从相同TCP首部的确认应答号所指位置开始能够接收的数据大小(8位字节)。TCP不允许发送超过此处所示大小的数据。不过,如果窗口为0,则表示可以发送窗口探测,以了解最新的窗口大小。但这个数据必须是1个字节。
校验和(Checksum)
- 源IP地址与目标IP地址在IPv4的情况下都是32位字段,在IPv6地址时都为128位字段。
- 填充是为了补充位数时用,一般填入0。
TCP的校验和与UDP相似,区别在于TCP的校验和无法关闭。
TCP和UDP一样在计算校验和的时候使用TCP伪首部。这个伪首部如上图所示。为了让其全长为16位的整数倍,需要在数据部分的最后填充0。首先将TCP校验和字段设置为0。然后以16位为单位进行1的补码和计算,再将它们总和的1的补码和放入校验和字段。
接收端在收到TCP数据段以后,从IP首部获取IP地址信息构造TCP伪首部,再进行校验和计算。由于校验和字段里保存着除本字段以外其他部分的和的补码值,因此如果计算校验和字段在内的所有数据的16位和以后,得出的结果是“16位全部为1(1的补码中该值为0(负数0)、二进制中为1111111111111111,十六进制中为FFFF,十进制中则为正整数65535。) ”说明所收到的数据是正确的。
■ 使用校验和的目的是什么?
有噪声干扰的通信途中如果出现位错误,可以由数据链路的FCS检查出来。那么为什么TCP或UDP中也需要校验和呢?
其实,相比检查噪声影响导致的错误,TCP与UDP的校验和更是一种进行路由器内存故障或程序漏洞导致的数据是否被破坏的检查。
有过C语言编程经验的人都知道,如果指针使用不当,极有可能会破坏内存中的数据结构。路由器的程序中也可能会存在漏洞,或程序异常宕掉的可能。在互联网中发送数据包要经由好多个路由器,一旦在发送途中的某一个路由器发生故障,经过此路由器的包、协议首部或数据就极有可能被破坏。即使在这种情况下,TCP或UDP如果能够提供校验和计算,也可以判断协议首部和数据是否被破坏。
紧急指针(Urgent Pointer)
该字段长为16位。只有在URG控制位为1时有效。该字段的数值表示本报文段中紧急数据的指针。正确来讲,从数据部分的首位到紧急指针所指示的位置为止为紧急数据。因此也可以说紧急指针指出了紧急数据的末尾在报文段中的位置。
如何处理紧急数据属于应用的问题。一般在暂时中断通信,或中断通信的情况下使用。例如在Web浏览器中点击停止按钮,或者使用TELNET输入Ctrl + C时都会有URG为1的包。此外,紧急指针也用作表示数据流分段的标志。
选项(Options)
选项字段用于提高TCP的传输性能。因为根据数据偏移(首部长度)进行控制,所以其长度最大为40字节。
另外,选项字段尽量调整其为32位的整数倍。具有代表性的选项如表所示。
类型2的MSS选项用于在建立连接时决定最大段长度的情况。这选项用于大部分操作系统。
类型3的窗口扩大,是一个用来改善TCP吞吐量的选项。TCP首部中窗口字段只有16位。因此在TCP包的往返时间(RTT)内,只能发送最大64K字节的数据(例如在RTT为0.1秒时,不论数据链路的带宽多大,最大也只有5Mbps的吞吐量。) 。如果采用了该选项,窗口的最大值可以扩展到1G字节。由此,即使在一个RTT较长的网络环境中,也能达到较高的吞吐量。
类型8时间戳字段选项,用于高速通信中对序列号的管理。若要将几个G的数据高速转发到网络时,32位序列号的值可能会迅速使用完。在传输不稳定的网络环境下,就有可能会在较晚的时间点却收到散布在网络中的一个较早序列号的包。而如果接收端对新老序列号产生混淆就无法实现可靠传输。为了避免这个问题的发生,引入了时间戳这个选项,它可以区分新老序列号。
类型4和5用于选择确认应答(SACK:Selective ACKnowledgement)。TCP的确认应答一般只有1个数字,如果数据段总以“豁牙子状态(这个形象的比喻是指数据段在途中丢失的情况。尤其是时不时丢失的情况。其结果就是在接收方收到的数据段的序号不连续,呈有一个没一个的状态。) ”到达的话会严重影响网络性能。有了这个选项,就可以允许最大4次的“豁牙子状态”确认应答。因此在避免无用重发的同时,还能提高重发的速度,从而也能提高网络的吞吐量。
■ 窗口大小与吞吐量
TCP通信的最大吞吐量由窗口大小和往返时间决定。假定最大吞吐量为Tmax ,窗口大小为W,往返时间是RTT的话,那么最大吞吐量的公式如下:
假设窗口为65535字节,RTT为0.1秒,那么最大吞吐量Tmax 如下:
以上公式表示1个TCP连接所能传输的最大吞吐量为5.2Mbps。如果建立两个以上连接同时进行传输时,这个公式的计算结果则表示每个连接的最大吞吐量。也就是说,在TCP中,与其使用一个连接传输数据,使用多个连接传输数据会达到更高的网络吞吐量。在Web浏览器中一般会通过同时建立4个左右连接来提高吞吐量。