计算机网络实验GoBackN滑动窗口协议C++

计算机⽹络实验GoBackN滑动窗⼝协议C++环境 : Microsoft Visual C++ 6.0
Go Back N 协议(暂⽆ ack )
#include <iostream>
#include <cstring>
#include "protocol.h"
#include "datalink.h"
using namespace std  ;
#pragma comment ( lib  , "Protocol.lib" )
#define rep ( i , j , n ) for ( int i = int(j) ; i < int(n) ; ++i )
// 帧类型
#define FRAME_DATA 1
#define FRAME_ACK  2
粉体气力输送系统// 窗⼝⼤⼩定义
#define MAX_SEQ 7
// 超时规定
#define DATA_TIMER  1200
// 帧数据结构定义
namespace YHL {
class FRAME {
public:
unsigned char type ;            // 种类
unsigned char ack ;            // ack
unsigned char seq ;            // 序号
unsigned char data[PKT_LEN] ;  // 数据部分
unsigned int  padding ;
public:
FRAME () {}
FRAME ( unsigned char _seq , unsigned char _ack )
: seq ( _seq )
, ack ( _ack )
{}
} One ;    // One 作为反复使⽤的帧
// 事件参数
int arg = 0 ;
// 物理层是否准备好了
int phl_ready = 0 ;
// 发送⽅的左边界
unsigned char ack_expected = 0 ;
// 发送⽅的右边界 + 1
unsigned char next_frame_to_send = 0 ;
// 接受窗⼝正在移动的号
unsigned char frame_expected = 0 ;
// 发送窗⼝的数量
unsigned char nbuffered = 0 ;
/
/ 存储发送窗⼝
unsigned char out_buf[MAX_SEQ+1][PKT_LEN] ;
// 令窗⼝滑动, 不超过 MAX_SEQ
unsigned char Go_On ( unsigned char &NO ) {
return NO = ( NO + 1 ) % ( MAX_SEQ + 1 ) ;
dsp2812}
// 判断 ack 是否落在发送窗⼝内
int between ( unsigned char a , unsigned char b , unsigned char c ) {
return ( ( ( a <= b ) && ( b < c ) )
|| ( ( c < a ) && ( a <= b ) )水泥胶砂振动台
|| ( ( b < c ) && ( c < a ) ) ) ;
}
// 添加 CRC 校验, 发往物理层
void Add_Crc_and_Send ( unsigned char *frame , int len ) {
void Add_Crc_and_Send ( unsigned char *frame , int len ) {
*(unsigned int *)( frame + len ) = crc32 ( frame , len ) ;
send_frame ( frame , len + 4 ) ;
phl_ready = 0 ;
}
// 发送⼀个数据帧
void Send_Data_Frame ( unsigned char frame_nr ,
unsigned char frame_expected ) {
int ack = ( frame_expected + MAX_SEQ ) % ( MAX_SEQ + 1 ) ;
FRAME One ( frame_nr , ack ) ;
// 根据序号 frame_nr 获取要发送的数据字段
memcpy ( One.data , out_buf[frame_nr] , PKT_LEN ) ;
dbg_frame ( "Send DATA %d %d , ID %d\n" , One.seq , One.ack , *(short *)One.data ) ;        Add_Crc_and_Send ( (unsigned char *)&One , 3 + PKT_LEN ) ;
start_timer ( frame_nr % MAX_SEQ , DATA_TIMER ) ;
}
// ⽹络层准备好了
void Net_Layer_OK ()  {
++nbuffered ;
get_packet ( out_buf[next_frame_to_send] ) ;
Send_Data_Frame ( next_frame_to_send , frame_expected ) ;
拉挤模具
Go_On ( next_frame_to_send ) ;
}
// 收到⼀个数据帧
void Recieve_Data () {
// 先进⾏校验
int len = recv_frame ( (unsigned char *)&One , sizeof One ) ;
if ( len < 5 || crc32 ( (unsigned char *)&One , len ) ) {
dbg_frame ( "Recv Bad packet\n" ) ;
return ;
}
/
/ 如果的确是接收窗⼝当前的序号
if ( One.seq == frame_expected ) {
dbg_frame ( "Recv DATA %d %d , ID %d\n" , One.seq , One.ack , *(short *)One.data ) ;            put_packet ( One.data , len - 7 ) ; // 减去七位⾮数据位
Go_On ( frame_expected ) ;
}
// 看是否可以腾出发送窗⼝的左边
机读答题卡while ( between ( ack_expected , One.ack , next_frame_to_send ) ) {
--nbuffered ;
stop_timer ( ack_expected ) ;
伞型齿轮Go_On ( ack_expected ) ;
}
}
// 协议初始化
void Init_Protocol ( int argc , char **argv ) {
protocol_init ( argc , argv ) ;
lprintf ( "Fluence_YHL : " __DATE__"  "__TIME__"\n" ) ;
disable_network_layer () ;
}
// 如果 ack 超时了
void Data_Time_Out () {
dbg_event ( "---- DATA %d timeout\n" , arg ) ;
// 要传的下⼀帧是 ack_expected, 也就是左边界
next_frame_to_send = ack_expected ;
for ( int i = 1 ; i <= nbuffered ; ++i ) {
Send_Data_Frame ( next_frame_to_send , frame_expected ) ;
Go_On ( next_frame_to_send ) ;
}
}
// 控制⽹络层开闭
void Enable_Net_Layer () {
if ( nbuffered < MAX_SEQ && phl_ready )
enable_network_layer() ;
else
disable_network_layer() ;
disable_network_layer() ;
}
// 获取⼀个事件
int Get_event () {
return wait_for_event ( &arg ) ;
}
}
int main ( int argc , char **argv ) {
YHL::Init_Protocol ( argc , argv ) ;
while ( true ) {
/
/ 获取⼀个事件
int event = YHL::Get_event () ;
switch ( event ) {
// ⽹络层准备好了
case NETWORK_LAYER_READY : YHL::Net_Layer_OK () ; break ;            // 收到⼀个帧
case FRAME_RECEIVED : YHL::Recieve_Data () ; break ;
// 物理层准备好了
case PHYSICAL_LAYER_READY : YHL::phl_ready = 1 ; break ;
// 超时重发
case DATA_TIMEOUT : YHL::Data_Time_Out () ; break ;
//
default : break ;
}
// 控制⽹络层流量
YHL::Enable_Net_Layer () ;
}
return 0 ;
}

本文发布于:2024-09-21 17:28:23,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/1/100061.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:发送   是否   滑动   络层   获取
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议