TCP 的基本传送单位是 TCP 段,TCP 段由 TCP 首部和数据内容组成,如下图所示:
Wireshark TCP 包如下图所示
其中首部长度是 44位,数据内容为空,下面将重点介绍首部格式。
TCP 首部
TCP 首部格式
源端口(Source Port)和目的端口(Destination Port)
长度: 16位(2字节)
描述:
-
源端口定义发送该报文段的应用程序的端口号;
-
目的端口定义接收该报文段的应用程序的端口号。
目标: 用于定位源端点的应用进程和目的端点的应用进程。
序列号(Sequence Number)和 确认号(Acknowledgment Number)
长度: 32位(4字节) 描述:
- 定义数据段中的数据部分在发送方数据流中的位置,也就是发送的数据部分第1个字节的序列号。
- 定义报文段的接收方期望从对方接收的序列号,指明下一次希望得到的、来自另一方的序列号。
使用场景: 当建立一个TCP连接时,发送方主机发出一个随机的初始化序列号(ISN)给接收方,接收方将其加1后送回发送方,这意味着发送方可以发送下一个字节了。一旦数据开始传送,序列号和确认号将跟踪已发送了的那些数据。
首部长度(Header length)
长度: 4位 = 15*4=60
描述: 首部长度在20~60字节之间,由定长部分和变长部分构成,定长部分长度为20字节,变长部分是选项和填充,长度在0~40字节之间。
目标: 通过这个字段可以同时判断该TCP段的开始位置和结束位置。
标志(Flags)
长度: 6位
描述: 定义6种不同的控制位或标志位,在同一时间可设置一位或多位标志。 标志位的描述如下图所示:
| 标志 | 含义 |
|---|---|
| Nonce | 简称NS,由RFC 3540“Robust Explicit Congestion Notification (ECN) Signaling with Nonces”定义,防止隐藏ECN-nonce(显式拥塞通告随机数) |
| Congestion Window Reduced | 简称CWR,是由发送主机添加的,用于指示它收到了ECE标志置位的TCP段,并已按拥塞控制机制作出回应。该标志由RFC 3168“The Addition of Explicit Congestion Notification (ECN) to IP”定义。 |
| ECN-Echo | 简称ECE,也由RFC 3168定义。如果SYN置位,它指示对方TCP兼容ECN (显式拥塞通告);如果SYN清零,它指示在正常传输过程中收到了IP首部中设置有Congestion Experienced标志的数据包。 |
| URG | 表示紧急指针是否有效。有高优先级的信息需要传输 |
| ACK | 表示确认号是否有效 |
| PSH | 推送数据,表示接收方必须不缓存数据,将数据直接传递给应用层协议,而不必等到缓冲区满时才传送 |
| SYN | 在连接建立时对序列号进行同步 |
| FIN | 表示终止连接 |
待解答:这些值如果都是 1 的话,会怎么样呢?
窗口大小(Window size)
长度: 16位(2字节)
注意: 如果这个值为0,则标志接收方的 TCP 缓冲区已满,发送方应该停止发送数据。最大长度是65535字节
校验和(Checksum)
长度: 16位(2字节)
描述: 包括首部和主体部分,用于存储TCP段的校验和。校验和算法将TCP段的内容转换为一系列16位的整数,并将它们相加,接收方根据校验和判断传输是否正确。UDP是否使用校验和是可选的,而TCP使用校验和则是强制性的。
目标: 用于传输层差错检测,允许目的主机可以验证TCP段的内容和能够测试可能的破坏。
紧急指针(Urgent Pointer)
长度: 16位(2字节) 描述: 是一个正的偏移量,只有当紧急标志置位(值为1)时,这个字段才有效。如果URG指针被设置,接收方必须检查这个字段。
目标: TCP为了提高效率,数据不会直接发送到对方,一般都先放在数据缓冲区中,等到数据积累到一定的大小才会一起发送。紧急指针所指向的一段数据不必等待缓冲数据的积累,直接发送到对方。
选项(Options)
长度: 最多40字节
RFC 793规定首部必须可以被32位整除,所以如果定义了一个选项,但该选项只用了16位,那么必须使用填充(padding)字段补充16位,填充字段是由0组成的字段。
选项有两类,一类是单字节选项,包括选项列表结束和无操作;另一类是多字节选项,包括最大段长度、窗口扩大因子、时间戳、允许SACK和SACK。
选项列表结束(EOP)
该选项在选项列表末尾用于填充,只能使用一次,而且只能用于最后一个选项。如下图所示:
无操作(NOP)
该字段用作选项之间的填充,但是它通常用在另一个选项之前,以便使选项能够放在4字的间隙中。如下图所示:
最大段长度(Maximum Segment Size, MSS)
该选项定义为接收的最大数据长度。如下图所示:
MSS与 MTU 的区别
MSS是在连接建立阶段确定的。每一方均需定义它将在连接期间接收的报文段的MSS。如果某一方不定义MSS的大小,则用默认值,即536字节。这个数值在连接期间不变。 MTU是能够放在MAC帧中数据的数量。
窗口扩大因子(Window Scale)
首部中的窗口大小字段定义了滑动窗口值,范围可以从0至65535字节。当通信双方认为首部的窗口值还不够大的时候,在连接开始时使用窗口扩大因子来定义更大的窗口。如下图所示:
时间戳(Timestamp)
10字节选项,其格式如下:
- 发送端接收到回应报文时,计算测量往返时间(RTT)= 时间戳值 - 时间戳应答
- 防止序列号绕回(Protection Against Wrapped Sequence numbers, PAWS)。用时间戳和序列号的组合来标识一个报文段。例如,300:1001标识在时间300发送的序列号为1001的段;500:1001标识在时间500发送的序列号为1001的段。