TCP的三次握手&四次挥手?
网上已有较多相关资料,本文不做过多介绍,有兴趣可移步至TCP的11种状态,三次握手,四次挥手的原因。TCP是如何保证有序,不丢包,不重复的?
历史上的两个著名解决方案:
1. GBN(Go-back N):
- 整个发送队列共用一个timer,该计时器会为发送队列中最老的未确认包开启计时:如果超时还未收到确认包,会将计时包开始的所有包重发;
- 对接收端而言,收到unexpected(通过sequence-number可以判断,无序、重复)的包则直接丢弃,并发回一个ACK,它的值是已经被成功接收的有序包的最大序列号;
- 对发送端而言,收到重复的ACK直接无视,只会在timer耗尽后进行第一条中说明的重发。
2. 选择重传(selective repeat):
- 发送队列中的每个包都会有自己的timer,会对超时未确认的包分别做重传;
- 对接收端而言,收到unexpected的包也会缓存下来,放到接收队列里,并为其发回ACK,它的值就是该包的sequence-number;
- 对发送端而言,会根据收到的ACK来决定是否移动发送窗口。
现在使用的TCP在上述两个方案上改进而成:
- timer为整个队列中最老的,在发送端发生移动时会重启timer,如果超时未收到ACK,会发起重传;
- 对接收端而言,收到unexpected的包会缓存下来,放到队列里,并发回接收端已经有序的部分的最大sequence number;
- 对发送端而言,会根据ACK的值来确认,是否移动sliding window,如果收到了3个重复的ACK,会发起重传。
TCP的流量控制&拥塞控制?
为什么需要这两种控制?
- 我们知道,数据发送到接收端以后,会被放入buffer中,而buffer是操作系统分配的资源,大小有限。如果不对发送端的速率进行控制,过多的报文涌入接收端,会导致数据无处可放,网络吞吐量下降,甚至会造成死锁,因此对发送端的发送速率进行控制是很有必要的。
流量控制:
- 原理:接收端通过控制拥塞窗口的大小来控制可传输包的数量;
- 主要表现为:接收端传回拥塞窗口cwnd(Congestion window)的大小,发送端不可发送超过该大小的数据;
- 特殊说明:在收到cwnd=0时,发送端应该启动Persistence timer,该timer在超时时会发送探测报文,检测cwnd大小是否仍为0,这样做的目的,是防止传输过程中接收端传回的可写报文丢掉。
拥塞控制:
- 接收端通过自己网络状况,对cwnd大小进行控制,主要使用AIMD策略。