深入TCP(一)--TCP报文段首部分析

TCP是网络中的重点中的重点,网络也叫做IP/TCP协议,因此也能看出TCP的重要性。因此我便想按照三部分来叙述TCP的相关知识。

一、TCP报文格式

TCP协议主要分为两部分

(1)分段头:TCP为了实现端到端可靠传输所加上的控制信息

(2)数据:指由高层即应用层而来的数据。

深入TCP(一)--TCP报文段首部分析

二、TCP报文格式分析

2.1首部字段

源和目的端口:占16比特。用于多路复用/多路分解来自或送至上层应用的数据,端口用来标识同一台计算机的不同进程。

***和确认号:占32比特,这两个字段是TCP可靠传输服务的关键部分,***是该报文段首字节的字节流编号(TCP把数据看成是有序的字节流,TCP隐式地对数据流的每个字节进行编号)。这样理解可能更直观,当报文被分解成多个报文段时,***就是报文段首字节在整个报文的偏移量。确定号指定下一个期待的字节。TCP是全双工的,假设从主机A接收到主机B的数据,则主机A填充进报文段的确认号是主机A期望从主机B收到的下一个字节序号。还没理清这两者的关系?见深入TCP(3)---三次握手四次挥手:

报头长度(4位)以32位字长为单位。因为选项是不定长的,这就需要标识整个首部字段的长度(单位是32位字),即5+选项个数。4位,单位是32位字,所以首部最长是15*4=60字节,即选项最长是40字节(10个选项)。

保留:占6比特,为将来的应用而保留,目前置为"0"。

编码位(SYN、FIN、ACK、URG、PSH、RST)

URG紧急比特。指示报文段里存在着被发送方的上层实体标记为”紧急”数据,当URG=1时,其后的紧急指针指示紧急数据在当前数据段中的位置(相对于当前***的字节偏移量),TCP接收方必须通知上层实体。

ACK确认比热。当ACK=0时,表示该数据段不包含确认信息,当ACK=1时,表示该报文段包括一个对已被成功接收报文段的确认。

PSH推送比特。当PSH=1时,接收方在收到数据后立即将数据交给上层,而不是直到整个缓冲区满。

RST复位比特。用于重置一个已经混乱的连接(如主崩溃),也可用于拒绝一个无效的数据段或者拒绝一个连接请求。一般而言,如果你得到的数据段被设置了RST位,那说明你这一端有问题了。

SYN同步比特。用于建立连接过程,在连接请求中,SYN=1和ACK=0表示该数据段没有使用捎带的确认域,而连接应答捎带一个确认,即SYN=1和ACK=1

注:捎带是指对客户机到服务器数据的确认被装载在一个承载服务器到客户机的数据报文段中。

FIN终止比特。用于释放一个连接,表示发送方已经没有数据要传输了。此时,接收方可能继续接收数据,好在SYN和FIN数据段都有***,从而保证了这两种数据段以正确顺序被处理。

窗口大小占32比特。用于流控制(确保连接的任何一方都不会过快地发送过量的分组而淹没另一方),窗口大小指定了从被确认的字节算起可以发送多少个字节。

校验和占32比特。提供了额外可靠性,在计算检验和的时候,TCP的Checksum域设为0,如果数据域的字节数为奇数,则数据域填补一个额外的0字节。校验和算法:将所有的16位字按1的补码形式累加起来,取累加结果的补码。因此,当接收方执行同样计算时(包括Checksum域),结果应该是0。

紧急指针占16比特,参考标志字段的URG位。

选项选项部分是为了适合复杂网络环境和更好地服务于应用层设计的。TCP选项最长是40字节。详情见2.2。

数据:无任何数据的TCP段也是合法的,通常用于确认和控制信息。


2.2 选项字段


TCP选项部分很好出现在已经建立连接的会话中,只要出现在TCP连接建立阶段,即三次握手。TCP选项部分实际运用有以下几种:

(1)最大报文传输段(MMS, Maximum Segment Size)

用于发送发与接收方协商最大报文段长度(仅仅是净荷数据,不包括TCP首部字段)。TCP在三次握手中,每一方都会通告期望收到的MSS(MSS只出现在SYN数据包中),如果一方不接受另一方的MSS值,则使用默认的536字节净荷数据,即主机能够接受20+536字节的TCP报文段。

(2)窗口扩大选项(Window scaling)

TCP报文的窗口大小字段占16位,即最大值是65535,但随着时延和带宽比较大的通信产生(如卫星通信),需要更大的窗口满足性能和吞吐率,这就是窗口扩大选项存在的意义。例子见参考资料[2]。

Windows scaling占3个字节,最后一个字节是移位值(Shift count),即首部的窗口位数16向左移动,如移位值为14,则新的窗口最大值增大到65535*(2^14)。

窗口扩大选项是在TCP建立之初进行协商,如果已实现了窗口扩大,当不再需要扩大窗口时,发送移位值=0就可以恢复到原窗口大小,即65535。

(3)选择确认选项(SACK, Selective Acknowledgements)

考虑这样情况,主机A发送报文段12345,主机B收到135且报文无差错,SACK用来确保只重传缺少的报文段,而不是重传所有报文段。

SACK选项需要2个功能字节,一个用来指明使用SACK选项(SACK Permission),另一指明这个选项占多少字节。

那怎么形容丢失的报文段2,说明2的左右边界分别是1、3。TCP的数据报文是有字块边界的,而这种边界是由***表示的。

最多能指明多少个字节块的边界信息呢?答案是4个。这是因为选项字段最大是40字节,去除2个功能字节,***是32位即4字节,并且需要左右边界,所以(40-2)/8 = 4。

(4)时间戳选项(timestamps)

时间戳选项用来计算往返时间RTT,发送方在发送报文段时把当前时钟的时间值放入时间戳字段,接收方将该时间戳字段的值复制到确认报文中,当接收方收到确认报文,对比确认报文的时间戳(等于发送方发送报文段的时间戳)和现在的时钟,即可算出RTT。

时间戳选项还可用于防止回绕序号PAWS。***只有32位,每2^32个***就会回绕(想想环形队列),采用时间戳选项很容易区分相同***的报文段。

(5)NOP(NO-Operation)

TCP的头部必须是4字节的倍数,而大多数选项不是4字节倍数,不足的用NOP填充。除此之外,NOP也用于分割不同的选项数据,如窗口扩大选项和SACK之间使用NOP隔离(下面的实例将看到这一点)。

2.3URG-PSH联系与区别

URG:紧急标志位。当URG=1时,表明报文段中含有紧急数据,需要优先处理,之后在处理普通数据。紧急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。

PSH:催促标志位。当PSH=1时,TCP会立即创建一个报文并发送,接收端收到PSH=1的报文后,立即将接收缓冲区内数据向上交付给应用程序,而不是等待缓冲区满了之后再交付。

PSH标志是为了提示接收端的应用程序应该立即从TCP的接收缓冲区中拿走数据,为接收后续的数据腾出空间。

URG与PSH的区别:

两者都可理解为处理紧急数据的标志位,只是处理方法不同。URG的紧急数据仅在报文内,而PSH的紧急数据还在接收缓冲区内。

发送方URG有效的时候,发送的数据不用进入缓冲区而直接交付给上一层;
发送方PSH有效的时候,接收方收到后,发送的数据要进入缓冲区但不用等缓冲区满就交给上一层