作者rusynth (stw)
看板Network
标题Re: [问答] 关於 Computer Networking 书上的 rdt 2.2 receiver
时间Sat Aug 25 10:32:12 2012
※ 引述《a40136 (funnynose)》之铭言:
: Reveiver : 已在Wait for 0 from below state
: 接收端是在等待package 0
: 左侧条件式 rdt_rcv(rcvpkt) 不解释
: corrupt(rcvpkt) 判断封包是否烂掉
: has_seq1(rcvpkt) 判断是不是自己要的东西
: 假设以上2个为true 封包烂掉 or 拿到的封包是 package 0
: 则执行下面的动作 - > udt_send(sndpkt) 这里的sndpkt 是 (ACK,1,checksum)
: 也就是在告诉sender一次我收到package 1啦,进入Sender节奏
问题就是出在这里呀
当 receiver 接收到第一个 packet
这个时候 sndpkt 的内容是未知的,并不是 (ACK,1,checksum)
因为 receiver 必须从 Wait for 1 from below 回到 Wait for 0 from below
的过程,才会把 sndpkt 设定成 (ACK,1,checksum)
举例如下:
0. sender 和 receiver 初始化,都是重新、从头刚开始执行
1. sender 送出第一个 packet 0
2. packet 0 在传送过程 corrupt 了
3. receiver 接收到第一个 packet,发现 corrupt 了
4. 这个时候 receiver 的 sndpkt 并没有初始化过,sndpkt 的值未知
5. receiver 想要送出 sndpkt,问题是sndpkt 的值未知,
receiver 该如何送出 sndpkt 呢?
当然以 C 语言的观点,如果是用指标的话,sndpkt 此时可能是任何值
反正不管 receiver 传送任何值给 sender,只要不是(ACK,0,checksum)
都会被 sender 当成 corrupt packet,使得 sender 再重新传送一遍。
不过万一好死不死,上次执行过并已经结束的 receiver process 的
记忆体区段、里面刚好还有旧的 sndpkt 而且内容刚好是 (ACK,0,checksum),
更好死不死的,该相同位置记忆体刚好被分配给新的 receiver process 的
sndpkt 的指标,那 sender 岂不是刚好接到错误 (ACK,0),引起整个程式出错...
虽然这个机率低到不行就是了...
不过从演算法的观点来看,这样写感觉算是一个漏洞
在 sndpkt 的值未知的情况之下,意图传送这个未知的值
作者可能也发现这个问题,所以在第五版增加了 oncethru 这个变数来控制,
让 receiver 必须跑过一遍 Wait for 1 from below ==> Wait for 0 from below,
把 oncethru 设定成 1,之後receiver 在 Wait for 0 from below 遇到
corrupt packet 的时候,因为 oncethru 为1了,就会直接执行 udt_send(sndpkt)。
可是他还是没有考虑到,万一第一个 packet 就出错的话,
新修改的演算法,receiver 会连一个讯息都送不出去...
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 111.254.28.30