网络原理自顶向下三可靠数据传输原理实现SR选择重传协议
SR
在SR中,和GBN不同,SR是给每一个分组设置定时器,发送端只确认重传当前分组,而不是所有分组。接收端在接收到乱序的分组的时候会进行缓存,当前面的分组到达以后一起提交给应用层。
发送端
- 等待上层调用。这里和GBN一样
- 超时。超时哪个重传哪个
- 收到ACK。如果收到的是最小序号的ACK,那么base可以往前移动,也就是窗口滑动。如果收到其他序号的ACK。那么把这些ACK缓存。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| $base = 1; $nextSeqNum = 1; function rdt_send($data) { $checkSum = generateCheckSum($data); $packet[$nextSeqNum] = make_pkt($data, $checkSum, $nextSeqNum); udt_send($packet[$nextSeqNum]); start_timer($nextSeqNum); if ($timeNum = timeout()) { udt_send($packet[$timeNum]); } else if ($isAck = rdt_rev() && check($isAck)) { $ackNum = getAckNum($isAck); stop_timer($ackNum); if ($ackNum == $base) { ++$base; while(array_key_exists(++$ackNum, $cache)) { ++$base; } } else { $cache[$ackNum] = $ackNum; } } }
|
接收端
- 序号在rcv_base 至 rcv_base + N - 1内的分组被正确接受。如果该分组不是期望的分组,那么缓存,如果是,那么给应用层并且看缓存里面有没有后续,有就直接一起给应用层
- 序号在rcv_base - N 至 rcv_base - 1内的分组被正确接受。返回一个确认ACK。表示我已经收到了。
- 其他情况。忽略分组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| $expackNum = 1; function rdt_rev($packet) { if (check($packet)) { if ($packet['num'] > $expackNum && $packet['num'] < $expackNum + N - 1) { if ($packet['num'] == $expackNum) { $data = extract($packet); deliver_data($data); $ack = make_pkt(1, $expackNum); $expackNum++; udt_send($ack); $key = $expackNum + 1; while(array_key_exists($key, $cache)) { deliver_data($cache[$expackNum]); ++$expackNum; $key++; } } else { $cache[$packet['num']] = $packet; $ack = make_pkt(1, $packet['num']); udt_send($ack); } } } else { $ack = make_pkt(1, $expackNum); udt_send($ack); } }
|