疑问1:为什么需要差错检测
因为 TCP 底层是 IP 层的,并不能保证数据完整无缺的送到,送到的数据可能是错位的,所以需要差错检测。
疑问2:为什么需要序号
在 client 正确发送并且 server 正确接收到数据的时候,如果 server 的回复丢失了,那么 client 会继续发送重复的分组的,但是 server 在分组没有序号的情况下无法处理这个 client 新发送的分组,是应该丢弃,还是应该接受。
疑问3:为什么需要超时检测
在 client 正确发送数据,但是数据因为某处路由堵塞而导致丢包了,发送数据的一方不能一直等待恢复。所以在指定时间内没有收到回复的情况下,需要重新发送数据。
疑问4:为什么需要 pipeline
在使用 stop-and-wait 进行数据传输的过程中,传输效率是极低的,即使拥有较高速度的宽带,时间也大都在等待的时间过程中浪费掉了。
疑问5:Selective Repeat 中的窗口长度和序列长度的关系
上图中 receiver 回复给 sender 的 ack 都丢失了,但是 receiver 由于接收到了正确的数据,所以其 window 进行了前移。而 sender 的 window 却不能前移,因为 ack 都丢失了,sender 不知道自己发送的包是丢失了还是 receiver 回复的 ack 丢失了,所以只能重新再发一遍。这时, sender 会重复发送
pkt0,pkt1和pkt2,在 reseiver 再次收到这三个包的时候,pkt1和pkt0就和发送的数据在原始数据中的位置是不对应的,即 sender 和 receiver 两个窗口中的相同序号的位置和数据的原始位置不一致
要想解决这个问题,首先要思考的是这个触发这个问题的条件是什么!(定义好了一个问题,才能更好的解决这个问题)
假设序号的长度为N,窗口的长度为M。那么所有数据中任何一个连续的长度为N的序列,其序号都是不重复的。
会不会是 sender 发送的包丢失导致的?不会,因为 sender 发送的数据丢失了,receiver 也就不会接收到数据了,sender 和 receiver 的窗口都不会移动。也就是说 sender 的窗口是滞后于 receiver 的窗口的。如果两个窗口放在一个数据上,就可以如下图,黄色的双向箭头可以理解为一段长度为N的序列。
也就是只有在 receiver 接收到数据所以其 window 前移,而 sender 不知道 receiver 接收到数据,其窗口不能前移的时候可能会导致这个问题。导致这种问题出现的场景如下图,sender 发送没有收到 ack 的数据的时候,其序号和 receiver 中的序号虽然一致,但是数据的位置是错误的,可以参考图中红色的双向箭头。
那么想解决这种问题的关键是让 sender window 和 receiver window 处于一个长度为
N的序列之中,两个窗口偏离的最大的情况就是一个 sender 发送了 M个分组,receiver 接收到了 M个分组,但是 receiver 发送的 M个 ack 全部丢失,这个时候两个窗口完全偏离。如果这个时候两个窗口都在一个连续的长度为N的序列之中,那么就永远不会出现错位的问题了。也就是M和N的关系是2 * M <= N。