企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
完整的 TCP 头部如下图所示 ![](https://img.kancloud.cn/6e/54/6e54819173511a6be862500b13be7aa4_1021x305.png) ![](https://img.kancloud.cn/ff/ac/ffaccb2feea0c7a45e7f84c35bc22fe8_1442x318.png) ## 源端口号、目标端口号 上图中 源端口号 Source Port: 443 目标端口号 Destination Port: 9524 TCP 报文头部里没有源 ip 和目标 ip 地址,只有源端口号和目标端口号 源 IP、源端口、目标 IP、目标端口构成了 TCP 连接的「四元组」。一个四元组可以唯一标识一个连接。 ## 序列号(Sequence number) TCP 是面向字节流的协议,通过 TCP 传输的字节流的每个字节都分配了序列号,序列号(Sequence number)指的是本报文段第一个字节的序列号。 ![](https://img.kancloud.cn/f7/33/f733820efa3a26454df72549fa91f9de_1932x522.png) 序列号加上报文的长度,就可以确定传输的是哪一段数据。序列号是一个 32 位的无符号整数,达到 2^32-1 后循环到 0。 在 SYN 报文中,序列号用于交换彼此的初始序列号,在其它报文中,序列号用于保证包的顺序。 ## 确认号(Acknowledgment number, ACK) TCP 使用确认号(Acknowledgment number, ACK)来告知对方下一个期望接收的序列号,**小于此确认号的所有字节都已经收到**。 关于确认号有几个注意点: * 不是所有的包都需要确认的 * 不是收到了数据包就立马需要确认的,可以延迟一会再确认 * ACK 包本身不需要被确认,否则就会无穷无尽死循环了 * 确认号永远是表示小于此确认号的字节都已经收到 ![](https://img.kancloud.cn/c3/9c/c39cce6058b17052a2600c669b0dd928_1274x560.png) ## TCP Flags (标记) TCP 有很多种标记,有些用来发起连接同步初始序列号,有些用来确认数据包,还有些用来结束连接。TCP 定义了一个 8 位的字段用来表示 flags,大部分都只用到了后 6 个,如下图所示 ![](https://img.kancloud.cn/1b/0b/1b0b2a0bbe72dbb75372f370547dc2ce_1015x301.png) 通常所说的 SYN、ACK、FIN、RST 其实只是把 flags 对应的 bit 位置为 1 而已,这些标记可以组合使用,比如 SYN+ACK,FIN+ACK 等 最常见的有下面这几个: * SYN(Synchronize):用于发起连接数据包同步双方的初始序列号 * ACK(Acknowledge):确认数据包 * RST(Reset):这个标记用来强制断开连接,通常是之前建立的连接已经不在了、包不合法、或者实在无能为力处理 * FIN(Finish):通知对方我发完了所有数据,准备断开连接,后面我不会再发数据包给你了。 * PSH(Push):告知对方这些数据包收到以后应该马上交给上层应用,不能缓存起来 ## 窗口大小(Window Size) ![](https://img.kancloud.cn/4a/5b/4a5b2dcb12aa2b9f8760bf16696e4f0d_986x289.png) 可以看到用于表示窗口大小的"Window Size" 只有 16 位,也就是最大窗口大小是 65535 字节(64KB)。 由于太小,因此TCP 协议引入了「TCP 窗口缩放」选项 作为窗口缩放的比例因子,比例因子值的范围是 0 ~ 14,其中最小值 0 表示不缩放,最大值 14。比例因子可以将窗口扩大到原来的 2 的 n 次方,比如窗口大小缩放前为 1050,缩放因子为 7,则真正的窗口大小为 1050 \* 128 = 134400 窗口缩放值在三次握手的时候指定 # 测试题 1、如果一个 TCP 连接正在传送 5000 字节的数据,第一个字节的序号是 10001,数据被分为 5 段,每个段携带 1000 字节,请问每个段的序号是什么? 2、A B 两个主机之间建立了一个 TCP 连接,A 主机发给 B 主机两个 TCP 报文,大小分别是 500 和 300,第一个报文的序列号是 200,那么 B 主机接收两个报文后,返回的确认号是() * A、200 * B、700 * C、800 * D、1000 3、客户端的使用 ISN=2000 打开一个连接,服务器端使用 ISN=3000 打开一个连接,经过 3 次握手建立连接。连接建立起来以后,假定客户端向服务器发送一段数据`Welcome the server!`(长度 20 Bytes),而服务器的回答数据`Thank you!`(长度 10 Bytes ),试画出三次握手和数据传输阶段报文段序列号、确认号的情况。