网络原理自顶向下三可靠数据传输原理实现SR选择重传协议

网络原理自顶向下三可靠数据传输原理实现SR选择重传协议

SR

在SR中,和GBN不同,SR是给每一个分组设置定时器,发送端只确认重传当前分组,而不是所有分组。接收端在接收到乱序的分组的时候会进行缓存,当前面的分组到达以后一起提交给应用层。

发送端
  • 等待上层调用。这里和GBN一样
  • 超时。超时哪个重传哪个
  • 收到ACK。如果收到的是最小序号的ACK,那么base可以往前移动,也就是窗口滑动。如果收到其他序号的ACK。那么把这些ACK缓存。
//序号
$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)) {
        //等待接收方回传ack 并且没有出现错误
        //获取确认的序号
        $ackNum = getAckNum($isAck);
        stop_timer($ackNum);
        //判断这个ACK是不是base
        if ($ackNum == $base) {
            ++$base;
            //判断缓存有没有
            while(array_key_exists(++$ackNum, $cache)) {
                //如果下一个ack已经收到了,那么就把base接着往前移动
                ++$base;
            }
        } else {
            //缓存起来
            $cache[$ackNum] = $ackNum;
        }
    }
}
接收端
  • 序号在rcv_base 至 rcv_base + N - 1内的分组被正确接受。如果该分组不是期望的分组,那么缓存,如果是,那么给应用层并且看缓存里面有没有后续,有就直接一起给应用层
  • 序号在rcv_base - N 至 rcv_base - 1内的分组被正确接受。返回一个确认ACK。表示我已经收到了。
  • 其他情况。忽略分组
//期望的序号
$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);
                //序号对的
                //没有错,把数据交付给应用层并回传ack
                //把数据给应用层
                deliver_data($data);
                //回传ACK
                $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
                $ack = make_pkt(1, $packet['num']);
                udt_send($ack);
            }
        }
    } else {
        //没通过差错检测或者序号错误,我们回传一个上一个ack,告诉发送端上一个分组我们收到了,当前分组没收到。
        //回传ACK
        $ack = make_pkt(1, $expackNum);
        udt_send($ack);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值