TCP在IP数据包中的封装如下图所示,出去CRC字段,TCP首部之后称之为TCP数据。
图中组成TCP的各个字段详细划分:
源端口号:16Bits
目的端口号:16Bits
序列号(Sequence Number):建立TCP连接时,SYN包通知对端其初始序列号(ISN)。是一个32位无符号整数,计满后归零继续。
确认序列号:其值等于SN值加上收到数据有效载荷的长度,不包括CRC(SYN和FIN加1),当ACK为1时有效。
首部长:给出TCP首部32bit字段个数,当选项字段为空时,其值为5。
保留位:一般默认为全0.
标志位:URG,紧急指针有效;ACK,确认序号有效;PSH,接收方尽快将此报文交给应用层;RST,重建连接;SYN,发起建立连接;FIN,终止连接
窗口大小:用于流量控制,大小为字节数。
校验和:覆盖TCP首部和TCP数据。
紧急指针:URG为1时有效,紧急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。
TCP选项字段:常用选项如下;
1.MSS (Maximum Segment Size):MSS表示TCP传往另一端的最大块数据长度,在连接建立时(SYN)双方各自通告自己的Mss,否则默认为536字节(加上20字节IP报头和TCP报头构成576字节的IP数据报)。长度为4字节,格式如下:
kind=2(1Byte) | len=4(1Byte) | 最大报文长度 (2Bytes) |
2.Window Scale:W通过定义一个窗口扩大因子,使TCP的窗口定义从16bit增加为32bit。W只出现在含有SYN标志的报文里。长度为3字节,格式如下:
kind=3(1Byte) | len=3(1Byte) | 移位数(1Byte) |
3.Timestamp:发送方在报文中放置一个时间戳值,接受方在确认时返回这个值以及接受时的时间戳值,以此来计算RTT值。不一定出现在含有SYN标志的报文里。长度为10字节,格式如下:
kind=8(1Byte) | len=10(1Byte) | 时间戳值(4Bytes) | 回应时间戳值(4Bytes) |
4.SACK:包括SACK-Permit和SACk,发送方建立连接时在SYN包里发送一个SACK-Permit,表示在今后的传输中希望收到SACK选项,一旦开始连接,接受方发送SACK选项,通知发送方已经接收的不连续的数据块。该选项的长度不固定,由不连续数据块的个数决定。格式如下:
SACK-Permit,只允许在有SYN标志的TCP包中,也即TCP握手的前两个包中,分别表示各自是否支持SACK。
kind=4(1Byte) | len=2(1Byte) |
SACK选项:SACK通常都是由TCP接收方产生的,在TCP握手时如果接收到对方的SACK允许选项同时自己也支持SACK的话,在接收异常时就可以发送SACK包通知发送方。选项类型: 5(1Byte);选项长度: 可变,但整个TCP选项长度不超过40字节,实际最多不超过4组边界值。
+--------+--------+
| Kind=5 | Length |
+--------+--------+--------+--------+
| Left Edge of 1st Block |
+--------+--------+--------+--------+
| Right Edge of 1st Block |
+--------+--------+--------+--------+
| |
/ . . . /
| |
+--------+--------+--------+--------+
| Left Edge of nth Block |
+--------+--------+--------+--------+
| Right Edge of nth Block |
+--------+--------+--------+--------+
该选项参数告诉对方已经接收到并缓存的不连续的数据块,注意都是已经接收的,发送方可根据此信息检查究竟是哪个块丢失,从而发送相应的数据块。Left Edge of Block,表示不连续块的第一个数据的序列号;Right Edge of Block,表示不连续块的最后一个数据的序列号之后的序列号。表示(Left Edge - 1)和(Right Edge)处序列号的数据没能接收到。