【TCP】【首部】
二级入口
TCP首部组成
组成部分说明
文中有部分内容引用了《Linux 网络协议栈开发基础篇(十二)—— 使用wireshark分析TCP/IP协议中TCP包头的格式》中的内容
字段 | 说明 | 备注 |
---|---|---|
源端口和目的端口(4*8byte=32bit) | 端口号是传输层的内容,与应用程序绑定对应关系。当与网络层的IP地址结合起来后,就可以实现网络间应用程序的交互。 | 一个IP和一个端口也称为一个插口(socket);插口对(socketpair)=那源IP+源端口+目的IP+目的端口 |
***和确认号(2*32bit) | 两个字段是TCP可靠传输服务的关键部分。 ***是该报文段首字节的字节流编号(TCP把数据看成是有序的字节流,TCP隐式地对数据流的每个字节进行编号)。这样理解可能更直观,当报文被分解成多个报文段时,***就是报文段首字节在整个报文的偏移量。确定号指定下一个期待的字节。 TCP是全双工的,假设从主机A接收到主机B的数据,则主机A填充进报文段的确认号是主机A期望从主机B收到的下一个字节序号。还没理清这两者的关系?见下图(三次握手): |
|
首部长度(4bit) | 因为选项是不定长的,这就需要标识整个首部字段的长度(单位是32位即4byte),那么由此可见,首部长度范围【20byte-15*4=60byte】。 | |
保留(6bit) | ||
标志字段(6bit) | U R G 紧急指针(u rgent pointer)有效; A C K 确认序号有效; P S H 接收方应该尽快将这个报文段交给应用层; R S T 重建连接; S Y N 同步序号用来发起一个连接; F I N 发端完成发送任务 |
|
窗口大小(16bit) | 用于流控制(确保连接的任何一方都不会过快地发送过量的分组而淹没另一方),窗口大小指定了从被确认的字节算起可以发送多少个字节。 | |
校验和(16bit) | 检验和覆盖了整个的T C P报文段:T C P首部和T C P数据 | |
紧急指针(16bit) | ||
TCP选项(0或多个32bit) |
(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隔离(下面的实例将看到这一点)。 |
TCP选项只会出现在SYN报文中 |