上一篇 Introduction to Computer Networks - Reliable Transmission (上) 中提到了为什么会需要使用 Reliable Transmission
和 Reliable Transmission
有哪些方式,但任何方式都有好有坏,虽然 Reliable Transmission
可以提供稳定且可靠的传输,但也会遇到不少的挑战,详细内容就持续望下看吧。
Issues with Sliding Window Protocol
虽然使用 Sliding Window Protocol 可以一次发送多个封包且确保封包能正确收到(Reliable Transmission),但也会有他自己的问题存在。
当 Sender 在发送某个封包时,如果发生 Timeout 的话由于需要重送该封包导致 Window 无法滑动,所以会降低整体传送的效率。如果传入封包的过程中发生了封包遗失的话,就必须要等待到 Timeout 后重新发送该封包,而由于 Silding Window 的特性,当一个封包遗失( Receiver 无法回传 Ack)的话,就会使 Windown 停下来无法 Silding,导致传送效率下降。要尽快发现封包遗失的话就需要调整 Timeout 的时间,尽快发现无法从 Receiver 端接收 Ack 而重新发送遗失的封包的话才能儘早使 Window 继续 Silding,而能够尽快侦测封包遗失的话有三种方式Negative Acknowledgement (NAK)
Additional Acknowledgement
Selective Acknowledgement
How to improve this?
Negative Acknowledgement (NAK)
传统 Ack 模式是当 Receiver 接收到正确的封包时才会发送,如果今天 Receiver 接收到的是损毁的封包,那他也只会抛弃这个封包而持续等待 Sender 发生 Timeout 后的重发,而 Negative Acknowledgement
则是变成当 Receiver 接收到错误或是损毁的封包时,也会回传一个 Ack 给 Sender,带这个 Ack 代表 Receiver 没有接收到正确的封包
,当 Sender 接收到表示错误的 Ack 后就可以提早重送该封包而不用等到 Timeout。
Additional Acknowledgement
传统 Ack 模式下 Receiver 只会发送一个 Ack 表示收到某个 SeqNum
的封包,而 Additional Acknowledgement
则会发送多个 Ack 给 Sender,比如说如果封包 2 遗失了但 Receiver 端只收到了封包 3 那么 Receiver 就会发送 一组
Ack 表示 Receiver 接收到封包 3 并且 还没收到封包2
,简单来说就是 Receiver 不只会发送已收到指定封包的 Ack 还会多送一个用于表示目前接收状况的 Ack。
Selective Acknowledgement
如果 Sender 连续发送封包 2, 3, 4, 5, 6,而 Receiver 端只接收到了 3, 4, 5, 6 的话,Receiver 端就只会 选择性
的发送 Ack 3, 4, 5, 6,而当 Sender 端发现只有封包 2 没有回传 Ack 的话,就可以知道封包 2 可能已经损毁或遗失。
How to select the window size?
要决定适当的 Window size 也是 Sliding window protocol 重要的一点,设定良好的 window size 可以使资料传输更顺畅
对于 Sender 端来说,window size 代表一次可以发送几个封包而不用等待 Ack,最简单的方法便是利用Bandwidth
计算Delay * Bandwidth对于 Receiver 端来说有两种做法设定 Receiver 的 window size 为 1:代表即使 Sender 端发送了多个封包,但 Receiver 一次也只能接收一个封包且这个封包的 SeqNum
必须要按照顺序(落在非 RWS 中的 SeqNum
皆不会接收),虽然 Receiver 端会丢弃非按照顺序的封包,但由于 Sender 端迟迟没到被 Receiver 端丢弃的风包的 Ack 时也会重送一次(Timeout),所以即使 Receiver 端的 window size 只设定为 1 一样可以正常工作,只是传输速率会比较差。设定 Receiver 端的 window size 大小设定和 Sender 端一样即使 Receiver 端的 window size 设定的比 Sender 端大其实是没有用的,因为即使 Receiver 端可以接收更多的封包但 Sender 却没办法发送这麽多封包。
Finite Sequence Number
封包的 header 中会添加 Sequence Number 作为验证封包的 id,如果设计的 Sequence Number 小于 Sender 可以发送的封包数量(小于 Sender 端的 window size)那 Sequence Number 就需要 重複使用
How to distinguish between different frames of the same sequence number?
为了避免重複使用 Sequence Number 导致 Receiver 端无法辨认封包的问题,那就需要 正在传递的封包数量要小于 sequence number 的大小
,为了达到这个目的而定义了一个变数称为 MaxSeqNum
就适用于设定最多可以使用多少 sequence number,其大小为
虽然以上面的公式设定 MaxSeqNum
可以满足 RWS = 1 的状况(Stop and Wait Protocol),但如果一次传送多个封包的话就会发生问题,比如说如果 sequence number = 0 ~ 7 而 RWS = SWS = 8 - 1 = 7 这样的条件下会发生什么
所以如果只把 MaxSeqNum 设定为 SWS + 1 的话就不够安全可能会发生上述的问题,而比较严谨的方式是
如果这样设定后碰到刚刚的情况会发生什么?
RWS = SWS = (8 + 1) / 2 = 4.5 = 4Sender send sequence number 0, 1, 2, 3Receiver receive 0, 1, 2, 3 这时 Ack 0, 1, 2, 3 也全部丢失了Sender 没收到 Ack 0, 1, 2, 3 而引发 Timeout 重送 0, 1, 2, 3虽然和上面一样 Receiver 端已经 sliding window 到 4, 5, 6, 7,但由于 Sender 重送的 0, 1, 2, 3 并不在 Receiver 的 window 里面,所以不会有收到重複的封包的问题