计算机网络实验 Go Back N (带有ACK)滑动窗口协议 C++
续上次 计算机网络实验 Go Back N (不含 ACK)滑动窗口协议 C++
今天实现了 带有 ACK 的
环境 :Microsoft Visual C++ 6.0
代码实现:
#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
#define ACK_TIMER 300
// 帧数据结构定义namespace YHL {class FRAME { public:unsigned char type ; // 种类unsigned char ack ; // ackunsigned char seq ; // 序号unsigned char data[PKT_LEN] ; // 数据部分unsigned int padding ; public:FRAME () {}FRAME ( unsigned char _type , unsigned char _seq , unsigned char _ack ): type ( _type ), ack ( _ack ) , seq ( _seq ){}} One ; // One 作为反复使用的帧// 事件参数int arg = 0 ; // 物理层是否准备好了 int phl_ready = 0 ; // 发送方的左边界 unsigned char ack_expected = 0 ;// 发送方的右边界 + 1unsigned 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_SEQunsigned char Go_On ( unsigned char &NO ) {return NO = ( NO + 1 ) % ( MAX_SEQ + 1 ) ;} // 判断 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 ) { *(unsigned int *)( frame + len ) = crc32 ( frame , len ) ;send_frame ( frame , len + 4 ) ;phl_ready = 0 ;}// 发送一个数据帧void Send_Data_Frame ( unsigned char type , unsigned char frame_nr , unsigned char frame_expected ) {int ack = ( frame_expected + MAX_SEQ ) % ( MAX_SEQ + 1 ) ;FRAME One ( type , frame_nr , ack ) ;switch ( type ) {case FRAME_DATA : {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 , DATA_TIMER ) ; break ;}case FRAME_ACK : {dbg_frame("Send ACK %d\n" , One.ack ) ;Add_Crc_and_Send ( (unsigned char *)&One , 3 ) ;break ;}} stop_ack_timer () ; // 现在我已经发出去了, 所以先暂停 ack }// 网络层准备好了void Net_Layer_OK () {++nbuffered ; get_packet ( out_buf[next_frame_to_send] ) ;Send_Data_Frame ( FRAME_DATA , 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 ;}switch ( One.type ) {// 收到的是数据帧case FRAME_DATA : {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 ) ;start_ack_timer ( ACK_TIMER ) ;}break ;}// 收到的是 ACK 帧case FRAME_ACK : {dbg_event ( "Recv ACK %d\n" , One.ack ) ; break ;}default : break ;}// 看是否可以腾出发送窗口的左边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, 也就是左边界 // Go Back N 就体现在这里 next_frame_to_send = ack_expected ;for ( int i = 1 ; i <= nbuffered ; ++i ) {Send_Data_Frame ( FRAME_DATA , next_frame_to_send , frame_expected ) ;Go_On ( next_frame_to_send ) ;}}void ACK_Time_Out () {dbg_event ( "ACK %d time is out " , arg ) ;Send_Data_Frame ( FRAME_ACK , next_frame_to_send , frame_expected ) ;}// 控制网络层开闭void Enable_Net_Layer () {if ( nbuffered < MAX_SEQ && phl_ready )enable_network_layer() ;elsedisable_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 ;// case ACK_TIMEOUT : YHL::ACK_Time_Out () ; break ;default : break ;}// 控制网络层流量YHL::Enable_Net_Layer () ;}return 0 ;
}
程序结果:
计算机网络实验 Go Back N (带有ACK)滑动窗口协议 C++相关推荐
- 计算机网络笔记(5) 传输层滑动窗口协议(GBN、SR)
文章目录 滑动窗口协议(Sliding-window protocol) GBN(Go-Back-N/后退N帧协议) SR协议(Selective Repeat/选择重传协议) 滑动窗口协议(Slid ...
- c语言退回N帧滑动窗口协议,滑动窗口协议实验的报告.docx
滑动窗口协议实验的报告 滑动窗口协议实验报告 篇一:Exp1_滑动窗口协议_实验报告 Exp1 滑动窗口协议实验报告 [实验目标] ? 理解和掌握"滑动窗口"技术. ? 基于计算机 ...
- 计算机网络 TCP 滑动窗口协议 详解
滑动窗口机制解析: 1.窗口机制 滑动窗口协议的基本原理就是在任意时刻,发送方都维持了一个连续的允许发送的帧的序号,称为发送窗口:同时,接收方也维持了一个连续的允许接收的帧的序号,称为接收窗口.发送窗 ...
- 计算机网络实验5以太网链路帧实验,计算机网络实验-使用Wireshark分析以太网帧与ARP协议.docx...
编号:_______________ 本资料为word版本,可以直接编辑和打印,感谢您的下载 计算机网络实验-使用Wireshark分析以太网帧与ARP协议 计算机网络实验-使用Wireshark分析 ...
- 【计算机网络】数据链路层 : 流量控制 ( “流量控制“ 机制 | 停止-等待协议 | 滑动窗口协议 | 后退 N 帧协议 GBN | 选择重传协议 SR | 滑动窗口 与 流量控制、可靠传输 )
文章目录 一. 数据链路层 流量控制 二. 数据链路层 与 传输层 流量控制 机制 三. 数据链路层 流量控制 四. 数据链路层 流量控制 方法分类 五.停止等待协议 六.滑动窗口协议 七.滑动窗口协 ...
- 计算机网络之传输层:6、TCP流量控制、滑动窗口协议
传输层:6.TCP流量控制 实现流量控制的方法: TCP流量控制: 实现流量控制的方法: 停止等待协议和滑动窗口协议 TCP流量控制:
- TCP连续ARQ协议和滑动窗口协议
TCP协议通过使用连续ARQ协议和滑动窗口协议,来保证数据传输的正确性,从而提供可靠的传输. 一.ARQ协议 ARQ协议,即自动重传请求(Automatic Repeat-reQuest),是OSI模 ...
- 三句话介绍清楚滑动窗口协议/GBN/SR
滑动窗口协议.GBN.SR之间不得不说的故事 首先我们来介绍什么是滑动窗口协议 滑动窗口协议(Sliding Window Protocol),属于TCP协议的一种应用,用于网络数据传输时的流量控制, ...
- TCP 滑动窗口协议 详解
滑动窗口机制 (1).窗口机制 滑动窗口协议的基本原理就是在任意时刻,发送方都维持了一个连续的允许发送的帧的序号,称为发送窗口:同时,接收方也维持了一个连续的允许接收的帧的序号,称为接收窗口. ...
最新文章
- java记事本环境变量_java环境变量配置以及用记事本写程序
- 别在 Java 代码里乱打日志了,这才是正确的打日志姿势!
- (转)创业需要知道的13句话
- php 获得当月时间戳,php获取当前月与上个月月初及月末时间戳的方法
- 商场专柜私收银现象治理要点
- codeforces332B - Maximum Absurdity 线段数 or dp
- 数据库事物 jdbc事物 spring事物 隔离级别:脏幻不可重复读
- 点云质量评估_Chamfer Distance--倒角距离
- 单片机通过改变占空比改变电机转速c语言,直流电动机的调速 用单片机产生PWM控制...
- web前端开发前景如何
- 多个app用同一个签名文件_运动设备和运动APP的合理搭配
- 抢红包案例分析以及代码实现(二)
- 怎么把备忘录中的视频导到手机相册里
- 金山 V8 终端安全系统 默认弱口令漏洞
- Gif动图如何在线编辑?教你三步在线编辑动图
- 基本概念:转发和重定向
- 【白话机器学习】算法理论+实战之决策树
- iOS内购-iap-In-App Purchases-开发及注意事项
- Mac终端添加快捷命令
- 5G网络(手机Wifi)快速入门