数据包
Source Port(16位)
- 源端口
Destination Port(16位)
- 目标端口
Sequence Number(32位)
- 本报文段第一个字节的序列号
- 如果到达最大值了后就循环到0
- ISN(初始序列号)
- 在三次握手的过程当中,双方会用过SYN报文来交换彼此的 ISN
- ISN 并不是一个固定的值,而是每 4 ms 加一,溢出则回到 0,这个算法使得猜测 ISN 变得很困难
Acknowledgment Number(32位)
- 用来告知对方下一个期望接收的序列号,小于ACK的所有字节已经全部收到
Header Length(4位)
- 首部长度
- 固定部分为20字节
- 若有可选项内容,最长可以为60字节
- 计算方法(转换为十进制值后再乘以4)
保留(6位)
- 无用
TCP Flag(6位)
- ACK 确认
- SYN 同步
- FIN 释放连接
- URG 紧急标志位,表示的是此报文段中有紧急数据,将紧急数据排在普通数据的前面;当接受端收到此报文后后必须先处理紧急数据,而后再处理普通数据
- PSH 催促标志位,当发送端将PSH置为1时,TCP会立即创建一个报文并发送。接受端收到PSH为1的报文后就立即将接受缓冲区内数据向上交付给应用程序,而不是等待缓冲区满后再交付
- RST 用于重置由于主机崩溃或其他原因而出现错误的连接或者用于拒绝非法的报文段和拒绝连接请求
Window size value(16位)
- 2^16次方,实际上是不够用的
- 因此 TCP 引入了窗口缩放(可选项),作为窗口缩放的比例因子,这个比例因子的范围在 0 ~ 14,比例因子可以将窗口的值扩大为原来的 2 ^ n 次方
Checksum(16位)
- 防止传输过程中数据包有损坏,如果遇到校验和有差错的报文,TCP 直接丢弃之,等待重传
Urgent pointer(16位)
- 当标记位URG为1时启用,指向报文中,紧急数据的位置
可选项(32位的倍数)
- TimeStamp: TCP 时间戳,其中 kind = 8, length = 10, info 有两部分构成: timestamp和timestamp echo,各占 4 个字节
- MSS: 指的是 TCP 允许的从对方接收的最大报文段
- SACK:
- SACK_Permitted 选项,该选项只允许在 TCP 连接建立时,有 SYN 标志的包中设置,也即 TCP 握手的前两个包中,分别表示通信的两方各自是否支持 SACK
- SACK(选择性确认) 选项位于 Options 中。该选项参数告诉对方已经接收到并缓存的不连续的数据块,发送方可根据此信息检查究竟是哪些块丢失,从而发送相应的数据块。受 TCP 包长度限制,TCP 包头最多包含四组 SACK 字段
- Window Scale: 窗口缩放选项
可选项中的时间戳
计算RTT
- a 向 b 发送的时候,timestamp 中存放的内容就是 a 主机发送时的内核时刻 ta1
- b 向 a 回复 s2 报文的时候,timestamp 中存放的是 b 主机的时刻 tb, timestamp echo字段为从 s1 报文中解析出来的 ta1
- a 收到 b 的 s2 报文之后,此时 a 主机的内核时刻是 ta2, 而在 s2 报文中的 timestamp echo 选项中可以得到 ta1, 也就是 s2 对应的报文最初的发送时刻。然后直接采用 ta2 - ta1 就得到了 RTT 的值
防止序列号回绕问题
- 每次发包的时候都是将发包机器当时的内核时间记录在报文中,那么两次发包序列号即使相同,时间戳也不可能相同,这样就能够区分开两个数据包了
三次握手
基本过程
- 第一次握手:
- 客户端发送报文
SYN,seq=x
,进入SYN_SEND
状态 - 服务端收到报文,进入
- 客户端发送报文