三个单工协议


前置

几个假设:

  • 物理层、数据链路层和网络层各自是独立的处理进程
  • 机器A希望向B发送的是一个可靠的、面向连接的长数据流
  • 机器不会崩溃
  • 从网络层拿到的数据是纯数据

数据链路层与网络层、物理层之间的数据传送接口


wait_for_event(等待事件发生函数)

等待事件发生的函数,一旦有下列事件发生,函数就会产生结果输出

几个事件如下:

  • frame_arrival:帧到达的事件
  • cksum_err:校验核没有通过发错的事件
  • time_out:定时器超时的事件

Timer定时器:

  • start_timer,stop_timer:重传定时器
  • start_ack_timer,stop_ack_timer:稍带确认定时器

帧结构:

typedef struct
{
	frame_kind kind;	//帧类型
	seq_nr seq;		//数据号
	seq_nr ack;		//确认号
	packet info;		//分组信息,来源于网络层,是帧的纯数据,直接作为帧的载荷
}frame;



协议1:无限制的单工协议

  • 数据单向传送
  • 收发双方的网络层都处于就绪状态(随时待命)
  • 处理时间忽略不计(瞬间完成)
  • 可用的缓存空间无穷大(无限空间)

假设DLL之间的信道永远不会损坏或者丢失帧(完美通道)

typedef enum {frame_arrival} event_type;
#include"protocol.h"
void sender1(void)		//发送方
{
	frame s;
	packet buffer;
	while(true)
	{
		from_network_layer(&buffer);		//从网络层获取数据
		s.info = buffer;
		to_physical_layer(&s);				//传输到物理层
	}
}
void receiver1(void)
{
	frame r;
	event_type event;
	while(true)
	{
		wait_for_event(&event);		//等到某个事件发生
		from_physical_layer(&r);		//从物理层获取比特流
		to_network_layer(&r.info);		//将数据传输到网络层
	}
}

接收方文字描述:wait_for_event()等待某个事件的到来,在协议1里只有"帧到达"这个事件

  →一旦帧到达,就立马执行函数from_physical_layer(),从物理层里面拿比特流,拿回来之后分割成帧

  →再根据帧头帧尾的信息对它进行处理,最主要的就是提取出帧里面的信息(包组)……最后传递给网络层



协议2:单工的停→等协议

位避免收方被涌入的数据淹没,收方不再无脑接收所有数据

对应方法:收方回发一个哑帧,接收方收到哑帧,表明收方允许接收数据,此时再次发送下一帧数据


其实这个时候已经是双方的了,虽然收方只是传了一个很小的哑帧,所以严格上来讲该协议应该属于半双工协议

typedef enum {frame_arrival} event_type;
#include"protocol.h"
void sender1(void)		//发送方
{
	frame s;
	packet buffer;
	event_type event; 
	while(true)
	{
		from_network_layer(&buffer);		//从网络层获取数据
		s.info = buffer;
		to_physical_layer(&s);				//传输到物理层
		wait_for_event(&event);		//不再继续进行直到收到回复(等一个事件,等待哑帧的到来)
	}
}
void receiver1(void)
{
	frame r, s;
	event_type event;
	while(true)
	{
		wait_for_event(&event);		//等到某个事件发生
		from_physical_layer(&r);		//从物理层获取比特流
		to_network_layer(&r.info);		//将数据传输到网络层
		to_physical_layer(&s);			//向对方发送一个哑帧
	}
}



协议3:有错误信道的单工协议

信道不再是完美信道:有噪声就会产生差错,有差错就可能会引起以下这些问题

①有可能收到重复帧,如何解决?

  • 给每个帧一个独一无二的序列号,序号也可以用来重组排序
②收方接到了帧,但发现这个帧出现了错误通不过校验,怎么解决?
  • 增加机制: 对正确帧的确认,任何时候只有收到的帧通过校验,才向发方发送一个确认

③任何的帧(包括确认帧)都会在路上丢失,这样会导致对方一直等下去~

  • 肯定确认重传(PAR)(或称自动重传请求(ARQ))技术:发送方启动一个重传定时器,超时前如果收到收方的确认,拆除定时器,超时还未收到确认,重传并重置定时器


typedef enum {frame_arrival} event_type;
#include"protocol.h"
void sender3(void)
{
	seq_nr next_frame_to_send;
	frame s;
	packet buffer;
	event_type event;
	next_frame_to_send = 0;
	from_network_layer(&buffer);
	while(true)
	{
		s.info = buffer;
		s.seq = next_frame_to_send;
		to_physical_layer(&s);
		start_timer(s.seq);			//设置定时器
		wait_for_event(&event);
		if(event==frame_arrival)		//收到了回复帧
		{
			from_physical_layer(&s);		//从物理层里面拿数据
			if(s.ack==next_frame_to_send)
			{
				stop_timer(s.ack);		//关闭定时器
				from_network_layer(&buffer);	//准备传递下一个信息
				inc(next_frame_to_send);
			}
		}
	}
}
void receiver3(void)
{
	seq_nr frame_expected;
	frame r, s;
	event_type event;
	frame_expected = 0;
	while(true)
	{
		wait_for_event(&event);
		if(event==frame_arrival)
		{
			from_physical_layer(&r);
			if(r.seq==frame_expected)
			{
				to_network_layer(&r.info);
				inc(frame_expected);
			}
			s.ack = 1−frame_expected;	//对收到的帧进行确认
			to_physical_layer(&s);		//传回发送方
		}
	}
}

提高效率的方法:

  • 全双工
  • 捎带确认:确认帧直接和下一次要传的帧一起发送,不过也要设定定时器,不能死等
  • 批量发送:停→等协议是每收到一个确认才能发送下一帧,发送端等待时间太长,网络通信效率不高,为了提高效率,可以在等待的时间发送数据帧,这样大大减少了浪费的时间

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值