TCP常见知识点整理
前言
复习一下TCP常见知识点,包括建立连接的三次握手、断开连接的四次挥手、重传机制、滑动窗口、流量控制、拥塞控制
参考资料:
4.1 TCP 三次握手与四次挥手面试题 | 小林coding
TCP 三次握手和四次挥手(传输层) | JavaGuide
TCP 传输可靠性保障(传输层) | JavaGuide
计算机网络面试题,63道计算机网络八股文(2.2万字80张手绘图),面渣逆袭必看👍 | 二哥的Java进阶之路
一、建立连接
1. 三次握手是怎么做的
首先服务端监听端口进入LISTEN状态;客户端发送SYN报文随机初始化客户端序列号,进入SYNC_SENT状态;服务端接受报文返回SYN+ACK报文随机初始化服务端序列号,应答序列号为客户端序列号+1;进入SYNC_RCVD状态,然后客户端接受到报文返回ACK报文,应答序列号为服务端序列号+1,连接建立进入ESTABLISHED,服务端接收到ACK报文后连接建立进入ESTABLISHED
2. 为什么是三次握手而不是两次握手
三次握手而不是两次握手的主要原因是为了防止初始化历史连接,避免资源浪费,并且同步双方序列号
3. TCP的数据分片是怎么做的
IP包大于MTU会由IP层进行分片,但是IP层不可靠,TCP实现了基于MSS进行分片,MSS是MTU除去IP头部和TCP头部的数据长度,可以保证IP包不会大于MTU,TCP分片和重传都是基于MSS的
二、断开连接
1. 四次挥手是怎么做的
断开连接四次挥手,由客户端发送FIN报文表示不在发送数据但可继续接受数据,进入FIN_WAIT_1状态,服务端接收后返回ACK报文进入CLOSE_WAIT状态,之后可能继续发送数据,客户端接收ACK后进入FIN_WAIT_2状态,等待数据发送接收完成后,服务端发送FIN报文进入LAST_ACK,客户端接收FIN后发送ACK进入TIME_WAIT,服务端接收ACK后断开连接
2. 每次挥手丢失会发生什么
第一次挥手丢失客户端会重传,第二次挥手丢失客户端会重传服务端再次应答,第三次挥手丢失服务端会重传FIN,客户端超过FIN_WAIT_2时间限制会关闭连接,第四次挥手丢失服务端会重传,超过重传次数会关闭连接,客户端TIME_WAIT时间限制会关闭连接
3. TIME_WAIT的时间是多少,为什么
TIME_WAIT设置为2MSL也就是两倍的最大报文生存时间,一是为了至少允许一次的报文丢失,接收服务端重发的FIN,保证服务端优雅关闭,二是保证历史连接的数据能正常消亡,不被重复接收
4. 如果出现大量TIME_WAIT,要怎么办
出现大量TIME_WAIT的情况有:HTTP不是长连接,导致每次请求服务端都会主动断开连接;长连接超时,Nginx回调服务端主动断开连接,超时时间为keepalive_timeout;长连接数量超过限制,服务端断开连接,限制数量为keepalive_requests
三、重传机制
1. 超时重传是什么
超时重传RTO需要略大于往返RTT,实际情况下是动态计算的
2. 快速重传是什么
快速重传解决超时重传需要等待的问题,累计收到3个重复的ACK会触发重传
3. SACK解决了什么问题
SACK记录接收方已经接收的数据,表示发送方无需再次重传这部分数据
4. D-SACK解决了什么问题
Duplicate SACK(D-SACK)记录接收方重复接收到的数据,可以判断是ACK丢失还是包重复等情况
四、滑动窗口
1. 滑动窗口解决了什么问题
滑动窗口用于解决需要串行地等待应答再发送数据的问题
2. 发送方怎么维护滑动窗口
发送方维护SND.WND(发送窗口大小)、SND.UNA(下一个确认的序列号)、SND.NXT(下一个发送的序列号)将窗口分割为已发送已确认、已发送未确认、可发送未发送、不可发送四个部分
3. 接收方怎么维护滑动窗口
接收方维护RCV.WND(接收窗口大小)、RCV.NXT(下一个接收的序列号)将窗口分割成已接收、可接收、不可接收三个部分
五、流量控制
1. 流量控制是什么
接收方不能及时读取数据,导致接收窗口收缩,会通过响应报文反馈到发送方,发送方调整窗口大小
2. 接收方是怎么收缩接收缓冲区的
接收方操作系统在收缩接收缓冲区之前,会先收缩接收窗口,防止接收数据超出接收窗口,造成丢包
3. 窗口收缩到0之后会发生什么
当窗口收缩到0时,发送方会等待非0窗口通知,同时设置计时器,如果超时会发送窗口探测报文
4. 如何防止窗口过小的低效传输
为了防止接收方通告一个小窗口以及发送方发送一段小数据,导致低效传输,可以使用发送方的Nagle算法,即在数据都被确认时立即发送数据,未确认时累积到MSS再发送数据,或者接收方延迟ACK,两者不可同时使用
六、拥塞控制
1. 什么是拥塞控制
为了防止网络拥塞情况下,大量数据包的发送加剧网络拥塞情况,TCP利用慢启动、拥塞避免、拥塞发生、快速恢复算法实现拥塞控制
2. 拥塞窗口是什么,跟发送窗口有什么关系
TCP维护一个拥塞窗口cwnd,根据网络拥塞程度变化,发送窗口为拥塞窗口和接收窗口的较小值
3. 慢启动是怎么做的
慢启动初始化cwnd = 1,每收到一个ACK,cwnd+1,呈指数增长,达到慢启动阈值ssthresh进入拥塞避免
4. 拥塞避免是怎么做的
拥塞避免每经过一个RTT,cwnd+1,呈线性增长,知道出现丢包
5. 拥塞发生是怎么做的
出现丢包时,使用拥塞发生算法,一种基于超时重传,一种基于快速重传。基于超时重传的拥塞发生算法,将
ssthresh = cwnd / 2,cwnd = 1,进入慢启动;如果网络没有那么糟糕,可使用基于快速重传的拥塞发生,将cwnd = cwnd / 2,ssthresh = cwnd,进入快速恢复算法
6. 快速恢复是怎么做的
快速恢复算法在接收到3个重复的ACK时,将cwnd = ssthresh + 3,重传数据,再在接收到重复的ACK时,使cwnd + 1,直到接收到新数据,将cwnd = ssthresh,进入拥塞避免