TCP协议八股文详解
TCP与UDP的区别
- UDP是无连接不可靠的数据传输
- TCP是面向连接的:套接字由
(source_ip, source_port, target_ip, target_port)
四元组唯一标识 - TCP是可靠的数据传输:提供了无损坏、无间隙、非冗余、按序的数据流
UDP的优势
首部开销小,支持一对多,多对一的连接对象,传输速度快
TCP连接的建立和拆除
TCP连接的建立:三次握手
背烂了,懒得写了
TCP连接的拆除:四次挥手
TCP的可靠性
可靠传输机制及其用途
- 检验和: 用于检测分组中的比特错误
- 定时器:用于超时重传,解决丢包问题
- 序号:保证分组的有序性;检测冗余分组;检测丢包
- 确认(ACK):接收方逐个或累计确认收到的分组,通常携带分组序号,用于发送方检测丢包
- 否定确认:NAK,与ACK相反
- 窗口:提高传输性能,发送方仅限发送窗口内的分组,用于解决流量控制、网络拥塞问题
TCP的可靠数据传输
- TCP提供了无损坏、无间隙、非冗余、按序的数据流
- TCP保证可靠数据传输的机制:
- 序号与确认号机制
- 流量控制
- 拥塞控制
流量控制与拥塞控制的区别
- 流量控制旨在解决接收方缓存不足的问题,TCP中使用rwnd(receive_window)字段(TCP报文中维护)表示接收方可用缓存的大小,发送方应满足:
已发送的字节-已确认的字节 <= rwnd
- 拥塞控制旨在解决路由器缓存不足导致的丢包问题和由于共享链路吞吐量的限制导致的巨大排队时延的问题,TCP中使用cwnd(congestion_window) (发送方维护)控制发送方向网络中发送数据的速率,发送方应满足
已发送的字节-已确认的字节 <= cwnd
- 在流量控制和拥塞控制的同时作用下,TCP中发送方应满足
已发送的字节-已确认的字节 <= min{rwnd, cwnd}
序号与确认号
报文段(Segment)的序号:该报文首字节的字节流编号
累积确认:TCP只确认按序到达的最后一个序号
流量控制
TCP报文中,接收方维护一个rwnd(接收窗口)字段,rwnd=RcvBuffer-[LastByteRcv-LastByteRead]
:LastByteRead为上层应用已读取的字节。
rwnd为0的问题:当接受窗口为0时,发送方发送只有一个字节的报文段,获取最新的rwnd值
拥塞控制
TCP如何感知到网络拥塞:出现丢包现象
丢包如何定义:
- 超时
- 收到3个冗余ACK(为什么是三个:参考回答)
TCP拥塞控制算法
拥塞控制算法包括三个部分:1. 慢启动(slow start) 2. 拥塞避免 3. 快速恢复,这三个阶段的名字就感觉很迷惑,不知道怎么起的= =
发送方需要维护两个变量:
- cwnd:拥塞窗口,用于限制发送方发送的速率,
已发送的字节-已确认的字节 <= cwnd
,初始值为1MSS(最大报文段大小,Max Segment Size) - ssthresh: 慢启动阈值,初始值为cwnd/2,当出现丢包现象时,ssthresh会变为出现丢包事件时刻的cwnd的一半
慢启动
慢启动的流程:
- 当cwnd < ssthresh,每发送完一个cwnd窗口大小的字节流时,
cwnd *= 2
- 当cwnd >= ssthresh,进入拥塞避免阶段
- 当出现超时导致的丢包现象时,
ssthresh=cwnd/2; cwnd=1
并重新开始慢启动过程,重新发送超时的报文段 - 当出现冗余ACK导致的丢包现象时,
ssthresh=cwnd/2; cwnd /= 2
, 执行快速重传, 进入快速恢复阶段
慢启动这个名字就很让人困惑,其实本质上是指数扩大拥塞窗口,这怎么能叫慢呢。。。其实在慢启动出现之前,有一个没有考虑拥塞的爆炸增长的版本,相对而言慢启动还是慢了一些的 ref。
拥塞避免
当cwnd >= ssthresh时,发送方会从慢启动状态变为拥塞避免状态
拥塞避免的流程:
- 正常情况下,每发送完一个cwnd窗口大小的字节流时,
cwnd += 1 MSS
- 当出现超时导致的丢包现象时,
ssthresh=cwnd/2; cwnd=1
并重新开始慢启动过程,重新发送超时的报文段 - 当出现冗余ACK导致的丢包现象时,
ssthresh=cwnd/2; cwnd/=2
,执行快速重传, 进入快速恢复阶段
快速重传
在报文段的定时器过期之前重传丢失的报文段(。。。本以为有什么高深的快速方法,结果就是timeout之前重传,又让我想到了令人困惑的慢启动,人和人对快慢的理解并不相通)
快速恢复
当进入快速恢复阶段时,cwnd已经被减半了,另外对收到的每一个冗余ACK,cwnd += MSS。(例如,cwnd=12时收到了3个冗余ACK,ssthresh=6MSS, cwnd=6MSS+3MSS=9MSS),此后保持线性增长。
为什么超时和冗余ACK处理方式不同呢?
TCP协议中,因为冗余ACK导致的丢包现象并不如超时导致的丢包那样严重。其实也很好理解,网络中出现了超时一定是因为当前的网络拥塞,而冗余的ACK既然可以不断的从接收方传到发送方,证明网络当前的状况其实还好。对于这种现象,TCP认为没必要再从慢启动阶段重新来过了。
Reference
- 《计算机网络:自顶向下方法》第七版