我是靠谱客的博主 野性金针菇,最近开发中收集的这篇文章主要介绍计算机网络:可靠的传输协议计算机网络:可靠的传输协议,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

  • 计算机网络:可靠的传输协议
    • 1、网络中不可靠的情况
    • 2、解决网络不可靠的基本方法
    • 3、可靠的传输协议
      • 3.1、比特交换协议(alternating-bit protocol)
    • 3.2、回退N步(Go-Back-N)
      • 3.3、选择重传(SR)
    • 4、协议实现

计算机网络:可靠的传输协议

1、网络中不可靠的情况

  1. 数据损伤:二进制数据发生翻转,及0->1或1->0
  2. 数据丢失:发送的数据包在拥塞或故障的网络中被丢弃
  3. 顺序紊乱:数据包以不同于发送的顺序被接受

2、解决网络不可靠的基本方法

  1. 超时重传:解决数据丢失
  2. 校验码:验证数据是否损伤
  3. 确认报文:确认对端正确接受报文
  4. 报文序号:告知对端正确的报文顺序

3、可靠的传输协议

根据上面基本方法,来完成可靠的传输协议。

3.1、比特交换协议(alternating-bit protocol)

之所以被称为比特交换,是因为在此协议中,packet序号仅为两个值——0和1。发送端以0、1顺序轮循发送packet,接受端也以相应的0、1顺序轮循接受packet。

  1. 协议事件
    • 开始计时(timer_start)
    • 超时(timeout)
    • 停止计时(timer_stop)
    • 发送packet(send_pkt)
    • 接受packet(recv_pkt)
    • 创建packet(make_pkt)
    • 检查报文正确性(correct)
    • 获取报文序号(getseq)
  2. packet属性
    1. 数据packet(data_pkt)
      • 报文序号(seq_num)
      • 校验和(checksum)
      • 数据(data)
    2. 确认packet(ack_pkt)
      • 报文序号(seq_num)
      • 校验和(checksum)
  3. FSM
sender
send
wait
have_data
------------------
data_pkt = make_pkt(seq_num, data, checksum)
send_pkt(data_pkt)
timer_start
recv_pkt(ack)
&&correct(ack_pkt)
&&eq_num == getseq(ack_pkt)
------------------
timer_stop
seq_num = (seq_num + 1) % 2
timeout()
------------------
^
^
------------------
send_pkt(data_pkt)
timer_start
recv_pkt(ack_pkt)
&&(notcorrect(ack_pkt)
||getseq(ack_pkt) != seq_num)
------------------
^
seq_num = 0
ps:
‘------’上方为条件,下方为发生事件
‘^’为无事发生
send_data
wait_ack
resend
recver
wait
send
recv_pkt(data_pkt)
&&correct(data_pkt)
&&getseq(data_pkt) == seq_num
------------------
^
recv_pkt(data_pkt)
&& notcorrect(data_pkt)
------------------
^
recv_pkt(data_pkt)
&&correct(data_pkt)
&&getseq(data_pkt) != seq_num
------------------
^
^
------------------
ack_pkt = make_pkt(getseq(data_pkt), ack, checksum)
send_pkt(ack_pkt)
^
------------------
ack_pkt = make_pkt(seq_num, ack, checksum)
send_pkt(ack_pkt)
seq_num = (seq_num + 1) % 2
seq_num = 0
ps:
‘------’上方为条件,下方为发生事件
‘^’为无事发生
wait_data
send_ack
duplicate_pkt

3.2、回退N步(Go-Back-N)

在回退N步的协议中,允许发送放发送多个packet,而不需等待确认,但它也受限于最大未确认packet数N。当所有packet被确认,则停止计数器;如果有一个未确认的报文则重转整个N个packet。

  1. 协议事件
    • 开始计时(timer_start)
    • 超时(timeout)
    • 停止计时(timer_stop)
    • 发送packet(send_pkt)
    • 发送所有未确认packet(send_pkt_all)
    • 接受packet(recv_pkt)
    • 创建packet(make_pkt)
    • 检查报文正确性(correct)
    • 获取报文序号(getseq)
  2. packet属性
    1. 数据packet(data_pkt)
      • 报文序号(seq_num)
      • 校验和(checksum)
      • 数据(data)
    2. 确认packet(ack_pkt)
      • 报文序号(seq_num)
      • 校验和(checksum)
  3. FSM
sender
next_seq < base + N
----------------------------
^
^
----------------------------
data_pkt = make_pkt(next_seq, data, checksum)
send_pkt(data_pkt)
if(next_seq == base) timer_start()
next_seq++
timeout()
----------------------------
^
^
----------------------------
send_pkt_all(data_pkt)
timer_start()
recv_pkt(ack_pkt)
&&correct(ack_pkt)
----------------------------
^
^
----------------------------
base = getseq(ack_pkt) + 1
timer_stop()
if(base != next_seq) timer_start()
recv_pkt(ack_pkt)
&& notcorrect(ack_pkt)
----------------------------
^
N = 8
base = 1
next_seq = 1
ps:
‘------’上方为条件,下方为发生事件
‘^’为无事发生
wait
send
timeout
ack
recver
recv_pkt(data_pkt)
&&correct(data_pkt)
&&getseq(data_pkt) == expect_seq
----------------------------
expect_seq++
^
----------------------------
ack_pkt = make_pkt(expect_seq - 1, ack, checksum)
send_pkt(ack_pkt)
default
----------------------------
send_pkt(ack_pkt)
expect_seq = 0
ack_pkt = make_pkt(0, ack, checksum)
ps:
‘------’上方为条件,下方为发生事件
‘^’为无事发生
wait
recv

3.3、选择重传(SR)

在GBN协议中,单纯的丢弃顺序紊乱的packet是很浪费的行为,SR协议允许接受顺序紊乱的报文,并回传相应的ack序号,使传输端选择性发送出错数据。但与此同时会增加ack packet的传输量,并使协议更加复杂。
ps:假设序号范围无限大

  1. 协议事件
    • 开始计时(timer_start)
    • 超时(timeout)
    • 停止计时(timer_stop)
    • 发送packet(send_pkt)
    • 接受packet(recv_pkt)
    • 创建packet(make_pkt)
    • 检查报文正确性(correct)
    • 获取报文序号(getseq)
    • 是否已接受相同的序号的packet(has_seq)
    • 下一个最小未确认序号(next_base)
  2. packet属性
    1. 数据packet(data_pkt)
      • 报文序号(seq_num)
      • 校验和(checksum)
      • 数据(data)
    2. 确认packet(ack_pkt)
      • 报文序号(seq_num)
      • 校验和(checksum)
  3. FSM
sender
next_seq < base + N
----------------------------
^
^
----------------------------
i = next_seq
data_pkt_i = make_pkt(next_seq, data, checksum)
send_pkt(data_pkt_i)
timer_start(i)
next_seq++
default
----------------------------
^
timeout()
----------------------------
^
^
----------------------------
send_pkt(data_pkt_i)
timer_start(i)
recv_pkt(ack_pkt)
&&correct(ack_pkt)
&&getseq(ack_pkt) >= base
----------------------------
^
^
----------------------------
base = next_base(getseq(ack_pkt))
N = 8
base = 1
next_seq = 1
ps:
‘------’上方为条件,下方为发生事件
‘^’为无事发生
wait
send
timeout
ack
recver
recv_pkt(data_pkt)
&&correct(data_pkt)
&&getseq(data_pkt) < base + N
&& nothas_seq(getseq(data_pkt))
----------------------------
^
^
----------------------------
ack_pkt = make_pkt(getseq(data_pkt), ack, checksum)
send_pkt(ack_pkt)
recv_pkt(data_pkt)
&&correct(data_pkt)
&&has_seq(getseq(data_pkt))
----------------------------
^
^
----------------------------
ack_pkt = make_pkt(getseq(data_pkt), ack, checksum)
send_pkt(ack_pkt)
default
----------------------------
^
N = 8
base = 1
ps:
‘------’上方为条件,下方为发生事件
‘^’为无事发生
i为变量
data_pkt_i为第i个数据packet
wait
recv
duplicate
  1. 考虑序号大小是有限的情况
    假设窗口大小N=3,最大序号max_seq=3
    ps:’ * ‘表示已发送未确认,’ # ‘表示已接受数据,’ & '表示发送已确认
发送端接受端时间事件
*0|*1|*2|00| 1| 2| 00send_data 0、1、2
*0|*1|*2|0#0|#1|#2| 01recv_data 0、1、2
*0|*1|*2|0#0|#1|#2| 02send_ack 0、1、2
*0|*1|*2|0#0|#1|#2| 03drop_ack 0
*0|&1|&2|0#0|#1|#2| 04recv_ack 1、2
*0|&1|&2|0#0|#1|#2| 05resend_data 0
*0|&1|&2|0#0|#1|#2|#06recv_data 0(error)

发现在这种情况下,接受端以为重传的0序号数据包是来自新的0号数据包,导致很严重的错误。

当窗口大小和最大序号处于什么关系的时候,可以避免这种情况呢:
假设:
(w为窗口大小,k为最大序号)

  1. 接收方窗口边界为[m, m+w-1],一共w个数据包
  2. 发送放没有接受任何ack的情况下窗口大小为[m-w, m-1],一共w个数据包

所以要想没有混乱的数据包,只要k>=2w即可

4、协议实现

https://github.com/PigPigZzz/reliable_procotol

最后

以上就是野性金针菇为你收集整理的计算机网络:可靠的传输协议计算机网络:可靠的传输协议的全部内容,希望文章能够帮你解决计算机网络:可靠的传输协议计算机网络:可靠的传输协议所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(39)

评论列表共有 0 条评论

立即
投稿
返回
顶部