Re: [問答] 關於 Computer Networking 書上的 rdt 2.2 receiver

看板Network作者 (stw)時間13年前 (2012/08/25 10:32), 編輯推噓0(000)
留言0則, 0人參與, 最新討論串3/3 (看更多)
※ 引述《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
文章代碼(AID): #1GE3alWc (Network)
文章代碼(AID): #1GE3alWc (Network)