基本信息
面向连接
报文结构
前 20 个字节是固定的 ,后面有 4n 字节是根据需要而增加
的选项 (n 是整数)。因此 TCP 首部的最小长度是 20 字节。
序号 seq
范围 [0, 2^32-1] ,增加到最大值后,下一个值回到0(使用 mod 2^32 运算)
每一个字节表示一个序列号,seq值表示该报文的第一个字节的序列号
确认号 ack
期望收到对方下一个报文的 seq 。确认号为 N 表示到 seq N-1 为止的数据都已正常收到
标志位-保留位右侧
表示报文性质
ACK
仅当 ACK=1 时,确认号字段有效,为0时无效。
在连接建立后,所有报文都必须设置ACK=1
SYN
仅在三次握手建立连接时有效
当SYN=1,ACK=0时,表示请求建立连接,
对方若同意连接则响应SYN=1,ACK=1
FIN
用来释放一个连接
当FIN=1时,表明此报文的发送方的数据已发送完毕,并要求释放连接
窗口
通知发送端,接收端可接收的空间大小
校验合
检测是否有错误。检测到有差错,直接丢弃。
建立可靠连接 - 三次握手
在握手之前,
- 客户端结束 CLOSE,
- 服务器也结束 CLOSE,并进入 LISTEN。
客户端发送 SYN 报文,等待服务器回应
- 标志位为 SYN
- seq = x(x 一般取随机数)
- 进入 SYN-SENT
服务器对该包进行确认后,发送 SYN+ACK 报文,等待客户端确认
- 标志位为 SYN 和 ACK
- seq = y;
- ack = x + 1
- 进入 SYN-RECV
客户端发送ACK报文
- 标志位为 ACK
- seq = x + 1
- ack= y + 1
- 进入 ESTABLISHED
服务器端收到客户端的确认报文后,结束 SYN-RECV,进入 ESTABLISHED
释放连接 - 四次挥手
客户端发送 FIN报文,等待服务器回应
- seq = u
- 进入 FIN_WAIT_1
服务端发送 ACK报文,等待服务器关闭连接
- ack = u+1
- 进入 CLOSE_WAIT
- 客户端收到后
- 进入FIN_WAIT_2,等待服务器关闭连接
服务器关闭连接后,发送 FIN 报文,等待客户端确认
- seq = m
- 进入 LAST_ACK
客户端发送 ACK 报文,等待一段时间后关闭连接
- ack = m+1
- 进入 TIME_WAIT
- 服务端收到后
- 进入 CLOSED ,连接释放成功
数据传输
确认应答机制。没有收到应答,超时重传
停等协议(发送-等待-确认-再发送),发送方大部分时间处于等待状态
流水线协议,可以连续发送
滑动窗口机制,每次发送数据都回携带自己的接收能力,发送的数据在一个窗口内,已经确认的包 让窗口滑动使其移出窗口
延迟和累计确认,延迟等待一段时间,再一起确认
MSS:maximum segment size,最大报文段长度
拥塞控制
变量:
拥塞窗口 cwnd (Congestion Window)
接收窗口 rwnd
发送窗口 = min(cwnd, rwnd)
RTT(Round-Trip Time) 往返时间:
Tahoe 拥塞控制算法
- 慢启动 slow start
- 发送方启始 cwnd = 1
- 每次接收到 ACK 包后 ,cwnd+1
- 拥塞避免
- 当cwnd达到一定的阈值时,进入拥塞避免 (ssthresh)
- 拥塞窗口每经过一个RTT,大小将会加一
- 快速重传
- 超时重传(RTO:Retransmission Time Out):时间驱动
- 快速重传:
- 连续收到三个相同的确认包,立即重传
- 并且将
ssthresh
的值设置为当前cwnd
的一半,而 cwnd 减为1,重回 slow start 阶段。
Reno
包含Tahoe的三个算法,多了一个 Fast Recovery(快速恢复)算法
- 快速恢复 Fast Recovery
- 当收到三个重复的ACK或是超过了RTO时间且尚未收到某个数据包的ACK,Reno就会认为丢包了,并认定网络中发生了拥塞。
- Reno会把当前的ssthresh的值设置为当前cwnd的一半,但是并不会回到slow start阶段,而是将cwnd设置为(更新后的)
ssthresh+3MSS
,之后 cwnd 呈线性增长。
NewReno,改进了快速恢复算法