面试题答案
一键面试保证数据可靠传输的机制
- 校验和(Checksum):
- 原理:TCP 协议在发送端将待发送的数据和伪首部一起计算校验和,接收端收到数据后,以同样的方法计算校验和并与接收到的校验和比较。若两者一致,则认为数据在传输过程中未被破坏。
- 实际编程问题:校验和计算错误可能导致数据错误未被检测出来,但现代网络硬件和软件实现中这种情况极少发生。解决方法是遵循标准的校验和计算算法,如 RFC 中规定的算法,并在不同环境下进行充分测试。
- 序列号(Sequence Number):
- 原理:TCP 对每个发送的字节都分配一个序列号。接收端根据序列号按序重组数据,确保数据按发送顺序交付给应用层。发送端通过序列号来确认哪些数据已被接收端正确接收,以便重传未确认的数据。
- 实际编程问题:序列号回绕问题,即当序列号达到最大值后会重新从 0 开始,可能导致数据混淆。解决方法是通过时间戳选项(TCP Timestamp Option)扩展序列号空间,或者在长连接传输大量数据时,合理设置连接的存活时间和重连机制。
- 确认应答(ACK):
- 原理:接收端接收到数据后,会向发送端发送确认报文(ACK),告知发送端数据已成功接收。发送端只有收到对已发送数据的 ACK 后,才会继续发送后续数据。若在一定时间内未收到 ACK,则认为数据传输失败并进行重传。
- 实际编程问题:ACK 丢失问题,可能导致发送端不必要的重传。解决方法是设置合理的重传定时器,当定时器超时未收到 ACK 时重传数据。同时,可以采用快速重传机制,即当接收端连续收到多个失序的报文段时,重复发送相同的 ACK,发送端若收到多个相同的 ACK,则在定时器超时前进行重传。
- 重传机制:
- 原理:分为超时重传和快速重传。超时重传是指发送端在发送数据后,启动重传定时器,若定时器超时未收到 ACK,则重传数据。快速重传是当发送端收到 3 个或以上重复的 ACK 时,就认为有数据包丢失,立即重传丢失的数据包,而无需等待重传定时器超时。
- 实际编程问题:重传定时器的设置较为关键,设置过短会导致不必要的重传,增加网络负担;设置过长则会影响数据传输效率。解决方法是根据网络状况动态调整重传定时器,如采用 Karn 算法结合 RTT(往返时间)的估计来设置合理的重传定时器。
流量控制机制
- 滑动窗口(Sliding Window):
- 原理:发送端和接收端都维护一个窗口,接收端通过在 ACK 报文中通告自己的接收窗口大小(rwnd),告知发送端自己当前能够接收的数据量。发送端根据接收端通告的窗口大小以及自身的拥塞窗口大小(cwnd)来决定可以发送的数据量。滑动窗口允许发送端在未收到 ACK 的情况下,连续发送多个数据包,提高了传输效率,同时避免发送过多数据导致接收端缓冲区溢出。
- 实际编程问题:窗口死锁问题,即接收端由于某些原因(如应用层处理速度慢)未能及时调整接收窗口大小并通告给发送端,而发送端一直等待接收端扩大窗口才继续发送数据,导致双方都停止数据传输。解决方法是在发送端引入持续定时器(Persistent Timer),当发送端收到零窗口通告(rwnd = 0)时,启动持续定时器,定时器超时后,发送端发送一个只有 1 字节数据的探测报文,促使接收端更新窗口大小并通告给发送端。
- 拥塞控制:
- 原理:拥塞控制是为了防止网络出现拥塞,保证网络的稳定性。TCP 拥塞控制主要通过慢开始(Slow - Start)、拥塞避免(Congestion Avoidance)、快速重传(Fast Retransmit)和快速恢复(Fast Recovery)四个阶段来实现。在慢开始阶段,拥塞窗口(cwnd)初始化为一个 MSS(最大段大小),每收到一个 ACK,cwnd 就增加一个 MSS,使发送速率呈指数增长。当 cwnd 达到慢开始门限(ssthresh)时,进入拥塞避免阶段,此时每收到一个 ACK,cwnd 增加 1/cwnd 个 MSS,发送速率线性增长。当发生超时重传时,ssthresh 变为当前 cwnd 的一半,cwnd 重新设置为 1 个 MSS,进入慢开始阶段;当收到 3 个重复 ACK 时,执行快速重传和快速恢复,ssthresh 变为当前 cwnd 的一半,cwnd 设置为 ssthresh + 3 个 MSS,进入拥塞避免阶段。
- 实际编程问题:不同网络环境下,拥塞控制参数(如 ssthresh、cwnd 初始值等)的设置可能不合理,导致网络性能不佳。解决方法是采用自适应的拥塞控制算法,根据网络实时的带宽、延迟等状况动态调整参数,如 BBR(Bottleneck Bandwidth and RTT)拥塞控制算法,它通过探测瓶颈带宽和往返时间来更有效地利用网络资源。