TCP数据包由首部和数据组成,
每行4个字节(32位)
其中首部最少20个字节(5行),最多60个字节(15行),选项部分是可选的;
TCP首部并没有字段表明整个数据包的长度,是因为TCP数据包是包含在IP数据包中的,而IP数据包已有长度字段,除去IP首部和TCP首部,剩余部分就是TCP包的净荷数据。
1、 第一行:源端口2字节,目的端口2字节
表示发送方和接收方的端口号
2、 第二、三行:序列号4字节,确认号4字节
序列号是指该报文段在发送方数据字节流中的位置,在TCP字节流中,每个数据字节都被编号;
确认号是指本机希望收到的下一个字节的序号;
序列号和确认号分别对应报文发送方向和相反方向的数据流;
报文被分解成多个报文段时,序列号就是首字节在整个报文中的偏移量,确认号指定下一个期待的字节;
序列号和确认号的最大表示范围均为2^32-1=4294967295≈42.9亿;
3、 第四行:首部长度4位,保留6位,标志位6位,窗口大小16位
首部长度:
指明首部共有多少行(每行4个字节),则TCP首部的最大长度为(2^4-1)*4=60字节;
标志位6位,含义分别如下:
URG:紧急指针有效
ACK:确认序号有效
PSH:接收方尽快将这个报文段交给应用层
RST:重建连接
SYN:同步序号用来发起一个连接
FIN:发端完成发送任务
窗口大小:
即发送数据的窗口大小,告诉对方在不等待确认的情况下,可以发来多大的数据;这里表示的最大长度是2^16-1=65535,如需要使用更大的窗口大小,需要使用选项中的窗口扩大因子选项;
4、 第五行:TCP校验和16位,紧急指针16位
TCP校验和:【待补充】
紧急指针:
当URG标志为1时紧急指针才有效,紧急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号(即序列号到紧急指针之间的数据为紧急数据,后面的数据才是正常数据)。
第六行开始是选项部分:
每个选项的开始是1字节的kind字段,说明选项的类型。(这里描述的长度,包含kind和长度字节本身)。
1、kind=0:选项表结束(共1字节)
2、kind=1:无操作(共1字节)Nop:no operation
用于填充选项字段,使TCP首部长度为4字节的倍数;
3、kind=2:最大报文段长度(共4字节=1+1+2)MSS(Maxinum Segment Size)
第一个字节:kind的值,即0x02;
第二个字节:该段选项的长度,即0x04;
第三四字节:MSS的值,最大报文段长度(仅仅是净荷数据,不包括TCP首部字段);
TCP包最大净荷数据量为65495(=IP数据包最大长度65535-TCP包头20字节 - IP包头20字节);
用于发送方与接收方协商最大报文段长度。TCP在三次握手中,每一方都会通告期望收到的MSS(MSS只出现在SYN数据包中),如果一方不接受另一方的MSS值,则使用默认的536字节净荷数据,即主机能够接受20+536字节的TCP报文段。
4、kind=3:窗口扩大因子(共3字节=1+1+1)Window Scaling
第一个字节:kind的值,即0x03;
第二个字节:该段选项的长度,即0x03;
第三个字节:移位值(Shift count)S,表示把窗口值向左移动S位,得到实际窗口大小,移位值的取值范围是0~14,则窗口最大值为1GB,即65535*(2^14)=1073725440=10亿字节=1GB,在TCP建立连接时协商的。如果窗口已经扩大,当不再需要扩大时,发送S=0选项就可以恢复窗口大小到16位;(最大值14,即最大TCP序号限定为2^16 * 2^ 14 = 2^30 < 2^31。该限制用于防止字节序列号溢出。)
窗口扩大选项是在TCP建立之初进行协商,如果已实现了窗口扩大,当不再需要扩大窗口时,发送移位值=0就可以恢复到原窗口大小,即65535。
5、kind=8:时间戳选项(共10字节=1+1+4+4)Timestamps
第一个字节:kind的值,即0x08;
第二个字节:该段选项的长度,即0x0a;
第三到第六字节:时间戳,系统启动时开始记数(可能是每500毫秒加1),用于计算RTT和防止回绕序号(PAWS);
第七到第十字节:回送的时间戳,为收到的上一个报文的时间戳;
时间戳选项用来计算往返时间RTT,发送方在发送报文段时把当前时钟的时间值放入时间戳字段,接收方将该时间戳字段的值复制到确认报文中,当接收方收到确认报文,对比确认报文的时间戳(等于发送方发送报文段的时间戳)和现在的时钟,即可算出RTT。
时间戳选项还可用于防止回绕序号PAWS。序列号只有32位,每2^32个序列号就会回绕(想想环形队列),采用时间戳选项很容易区分相同序列号的报文段。
6、kind=4:选择确认选项SACK Selective Acknowledgements
第一个字节:kind的值,即0x04;
第二个字节:该段选项的长度;
考虑这样情况,主机A发送报文段12345,主机B收到135且报文无差错,SACK用来确保只重传缺少的报文段,而不是重传所有报文段。
SACK选项需要2个功能字节,一个用来指明使用SACK选项(SACK Permission),另一指明这个选项占多少字节。
那怎么形容丢失的报文段2,说明2的左右边界分别是1、3。TCP的数据报文是有字块边界的,而这种边界是由序列号表示的。
最多能指明多少个字节块的边界信息呢?答案是4个。这是因为选项字段最大是40字节,去除2个功能字节,序列号是32位即4字节,并且需要左右边界,所以(40-2)/8 = 4。
TCP首部结束之后的部分
------------------------------------
转载请注明出处,谢谢。
小方的专栏