当前位置: 首页 > news >正文

滑动窗口协议仿真(2024)

1.题目描述

滑动窗口协议以基于分组的数据传输协议为特征,该协议适用于在数据链路层以及传输层中对按 顺序传送分组的可靠性要求较高的环境。在长管道传输过程(特别是无线环境)中,相应的滑动窗口 协议可实现高效的重传恢复。附录 3 给出了一个选择性重传的滑动窗口协议的简单实现,以此为参考, 设计并实现一个滑动窗口协议的仿真,显示数据传送过程中的各项具体数据,双方帧的个数变化,帧 序号,发送和接受速度,重传提示等。


2.程序演示

 这里我们使用Socket来模拟滑动窗口协议,实现了双方帧的个数变化,帧序号,发送和接受速度控制,重传显示。

控制帧发送速度

双方帧的个数变化

丢失包


3.参考代码

接收端代码

#include <winsock2.h>
#include <iostream>
#include <list>
#include <time.h>
#include <unistd.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;//函数说明------------------------------
DWORD WINAPI ThreadFun(LPVOID lpThreadParameter);void init_app();//---------------------------------------
WSADATA wd;
SOCKET Socket;
sockaddr_in addrClient;
int len = sizeof(sockaddr_in);//变量------------------------------
struct Data {//消息类型定义int Type_ACK = 0;int Type_Msg = 1;int Type_Requst = 2;int Type_Retransmission=3;//消息内容int Msg_Code = 0;//消息序号int Msg_Type = 1;//消息类型int Msg_ACK=0;//是否已经ACK了char *Msg_Content[128];//消息内容int Send_WinSize = 4;//发送窗口大小
};Data Send_Msg_Data;
Data *Get_Msg_Data;
char Get_buf[1024] = {0}, send_buf[1024] = {0};int main() {//提示=======================================================================cout << "滑动窗口协议仿真(Socket模拟)_接收方" << endl;//初始化=======================================================================init_app();//==========================================================================
}DWORD WINAPI ThreadFun(LPVOID lpThreadParameter) {// 接受数据SOCKET This_Socket = (SOCKET) lpThreadParameter;cout << "*连接成功" << endl;// 循环接收客户端数据int ret = 0;do {//接收ret = recv(This_Socket, Get_buf, sizeof(Get_buf), 0);Get_Msg_Data = (Data *) Get_buf;cout << "\n收到消息:" << endl;cout << "类型:" << Get_Msg_Data->Msg_Type << " 序号: " << Get_Msg_Data->Msg_Code << endl;//发送if (Get_Msg_Data->Msg_Type==3){Send_Msg_Data.Msg_Type =3;} else{Send_Msg_Data.Msg_Type = 0;}Send_Msg_Data.Msg_Code = Get_Msg_Data->Msg_Code;memcpy(send_buf, &Send_Msg_Data, sizeof(Data));sleep(1);if (send(This_Socket, send_buf, sizeof(send_buf), 0) > 0) {cout << "\n回复帧:" << Send_Msg_Data.Msg_Code << " ACK" << endl;} else {cout << "\n失败回复:" << Send_Msg_Data.Msg_Code << " ACK" << endl;}} while (ret != SOCKET_ERROR && ret != 0);return 0;
}void init_app() {if (WSAStartup(MAKEWORD(2, 2), &wd) != 0) {cout << "WSAStartup Error:" << WSAGetLastError() << endl;return;}// 创建流式套接字Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (Socket == INVALID_SOCKET) {cout << "socket error:" << WSAGetLastError() << endl;return;}//绑定端口和ipsockaddr_in addr;memset(&addr, 0, sizeof(sockaddr_in));addr.sin_family = AF_INET;addr.sin_port = htons(8000);addr.sin_addr.s_addr = inet_addr("127.0.0.1");//服务端bind绑定if (bind(Socket, (SOCKADDR *) &addr, len) == SOCKET_ERROR) {cout << "bind Error:" << WSAGetLastError() << endl;return;}// 监听listen(Socket, 5);//主线程循环接收客户端的连接while (true) {cout << "*等待连接..." << endl;// 接受成功返回与client通讯的SocketSOCKET Client = accept(Socket, (SOCKADDR *) &addrClient, &len);if (Client != INVALID_SOCKET) {// 创建线程,并且传入与client通讯的套接字HANDLE hThread = CreateThread(NULL, 0, ThreadFun, (LPVOID) Client, 0, NULL);CloseHandle(hThread); // 关闭对线程的引用}}
}

发送端代码

#include<winsock2.h>//winsock2的头文件
#include<iostream>
#include <list>
#include <ctime>#pragma comment(lib, "ws2_32.lib")using namespace std;//定义========================
void Init_Socket();void *SendMsg(void *pVoid);int getRand(int min, int max);void Sycn();void Send_Win_Move();void Retransmission(int Num);//发送的数据=======================
struct Data {//消息类型定义int Type_ACK = 0;int Type_Msg = 1;int Type_Requst = 2;int Type_Retransmission = 3;//消息内容int Msg_Code = 0;//消息序号int Msg_Type = 1;//消息类型int Msg_ACK = 0;//是否已经ACK了char *Msg_Content[128];//消息内容int Send_WinSize = 4;//发送窗口大小
};//默认参数=======================
int Rand_Num = 5;//随机概率1/5
int Receiver_WinSize = 10;
int Send_WinSize = 5;
int Send_Size = 10;
int ACK_OutTime = 10;
int Send_Num = 100;
char *Send_Msg = "0123456789";
SOCKET Socket;
int Win_Now_Size = 0;//消息列表=======================
list<Data> MSG_Win_List;
Data Send_Msg_Data;
Data *Get_Msg_Data;
Data *Temp_Msg_Data;
int Num = 0;
char send_buf[1024] = {0}, Get_buf[1024] = {0};void init_data() {char auto_data;//提示=======================================================================cout << "*====滑动窗口协议仿真(Socket模拟)_发送方====*\n";cout << "\n-------------------------------\n";cout << " 请输入必要参数(y/n):";cin >> auto_data;if (auto_data == 'n') {cout << " 发送窗口: ", cout << Send_WinSize << endl;cout << " 消息帧数: ", cout << Send_Num << endl;
//        cout << " 发送内容: ", cout << Send_Msg << endl;} else {cout << " 发送窗口: ", cin >> Send_WinSize;cout << " 消息帧数: ", cin >> Send_Num;}cout << "-------------------------------" << endl;system("pause");}int main() {init_data();Init_Socket();//接收服务端的消息pthread_t tids;pthread_create(&tids, NULL, SendMsg, &Socket);//随时给服务端发消息do {int ret = 0;do {ret = recv(Socket, Get_buf, sizeof(Get_buf), 0);Get_Msg_Data = (Data *) Get_buf;if (ret != SOCKET_ERROR && ret != 0) {cout << "\n\n\t==>收到帧:" << " ACK: " << Get_Msg_Data->Msg_Code << endl;list<Data>::iterator iter;for (iter = MSG_Win_List.begin(); iter != MSG_Win_List.end(); iter++) {if (Get_Msg_Data->Msg_Code == iter->Msg_Code) {(*iter).Msg_ACK = 1;if (Get_Msg_Data->Msg_Type == 3) {cout << "\n\t重传删除了一个" << endl;Win_Now_Size--;MSG_Win_List.erase(iter);}break;}}Sycn();}} while (ret != SOCKET_ERROR && ret != 0);} while (true);//关闭监听套接字closesocket(Socket);WSACleanup();}void Init_Socket() {WSADATA wd;//加载winsock2的环境if (WSAStartup(MAKEWORD(2, 2), &wd) != 0) {cout << "WSAStartup  error:" << GetLastError() << endl;return;}//创建流式套接字Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (Socket == INVALID_SOCKET) {cout << "socket  error:" << GetLastError() << endl;return;}//连接服务器sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(8000);addr.sin_addr.s_addr = inet_addr("127.0.0.1");int len = sizeof(sockaddr_in);if (connect(Socket, (SOCKADDR *) &addr, len) == SOCKET_ERROR) {cout << "connect  error:" << GetLastError() << endl;return;}
}void *SendMsg(void *pVoid) {do {Send_Win_Move();Sycn();system("pause");Send_Msg_Data.Msg_Code = Num;Send_Msg_Data.Msg_Type = 1;memcpy(send_buf, &Send_Msg_Data, sizeof(Data));if (Win_Now_Size == Send_WinSize) {list<Data>::iterator iter;for (iter = MSG_Win_List.begin(); iter != MSG_Win_List.end(); iter++) {if (iter->Msg_ACK == 0) {Send_Msg_Data.Msg_Code = iter->Msg_Code;Send_Msg_Data.Msg_Type = 3;memcpy(send_buf, &Send_Msg_Data, sizeof(Data));if (send(Socket, send_buf, sizeof(send_buf), 0) > 0) {cout << "\n\t<==发送重传帧:" << iter->Msg_Code << endl;} else {cout << "\n\t<==失败发送重传帧:" << iter->Msg_Code << endl;}break;}}continue;}if (getRand(1, Rand_Num) == Rand_Num)//随机丢失{cout << "\n\t<=xxxx=随机丢失帧:" << Num++ << endl;} else {if (send(Socket, send_buf, sizeof(send_buf), 0) > 0) {cout << "\n\t<==发送帧:" << Num++ << endl;} else {cout << "\n\t<<==失败发送帧:" << Num++ << endl;}}Win_Now_Size++;Send_Num--;MSG_Win_List.push_back(Send_Msg_Data);} while (Send_Num > 0);
}void Send_Win_Move() {if (MSG_Win_List.begin()->Msg_ACK == 0) return;list<Data>::iterator iter=MSG_Win_List.begin();while (iter->Msg_ACK==1){MSG_Win_List.erase(iter);Win_Now_Size--;iter=MSG_Win_List.begin();}cout << "\n\t窗口移动了" << endl;
}int getRand(int min, int max) {return (rand() % (max - min + 1)) + min;
}void Sycn() {cout << "\n\t------------------------------" << endl;cout << "\t当前发送窗口:" << Send_WinSize << "\t可用窗口大小:" << Send_WinSize - Win_Now_Size << endl;list<Data>::iterator iter;for (iter = MSG_Win_List.begin(); iter != MSG_Win_List.end(); iter++) {cout << "\t#帧序号:" << iter->Msg_Code << "\t#是否ACK:" << iter->Msg_ACK << endl;}cout << "\t------------------------------" << endl;
}

 4.导入ws2_32库到Clion :

导入ws2_32库到Clion项目-CSDN博客

 

 2024 HNUST计算机网络课程设计-(ᕑᗢᓫ∗)˒芒果酱-参考文章

(代码可以参考,૮₍ ˃ ⤙ ˂ ₎ა 但同学们要认真编写哦)
-------------------------------------------------------------------------
1、网络聊天程序的设计与实现
C++ Socket 多线程 网络聊天室 支持用户端双向交流(2023)-CSDN博客
2、Tracert 与 Ping 程序设计与实现
Tracert 与 Ping 程序设计与实现(2024)-CSDN博客
3、滑动窗口协议仿真
滑动窗口协议仿真(2024)-CSDN博客
4、OSPF 路由协议原型系统设计与实现
OSPF 路由协议原型系统设计与实现-CSDN博客
5、基于 IP 多播的网络会议程序
基于 IP 多播的网络会议程序(2024)-CSDN博客
6、编程模拟 NAT 网络地址转换
编程模拟 NAT 网络地址转换(2024)-CSDN博客
7、网络嗅探器的设计与实现
网络嗅探器的设计与实现(2024)-转载-CSDN博客
8、网络报文分析程序的设计与实现
网络报文分析程序的设计与实现(2024)-CSDN博客
9、简单 Web Server 程序的设计与实现
简单 Web Server 程序的设计与实现 (2024)-CSDN博客
10、路由器查表过程模拟

计算机网络 - 路由器查表过程模拟 C++(2024)-CSDN博客

 

相关文章:

滑动窗口协议仿真(2024)

1.题目描述 滑动窗口协议以基于分组的数据传输协议为特征&#xff0c;该协议适用于在数据链路层以及传输层中对按 顺序传送分组的可靠性要求较高的环境。在长管道传输过程&#xff08;特别是无线环境&#xff09;中&#xff0c;相应的滑动窗口 协议可实现高效的重传恢复。附录 …...

uniapp上传文件时用到的api是什么?格式是什么?

在UniApp中&#xff0c;你可以使用uni.uploadFile()方法来上传文件。这是一个异步方法&#xff0c;用于将本地资源上传到服务器。 该方法的基本格式如下&#xff1a; uni.uploadFile({url: 上传接口地址,filePath: 要上传的文件路径,name: 后端接收的文件参数名,formData: {/…...

Java面试——框架篇

1、Spring框架中的单例bean是线程安全的吗&#xff1f; 所谓单例就是所有的请求都用一个对象来处理&#xff0c;而多例则指每个请求用一个新的对象来处理。 结论&#xff1a;线程不安全。 Spring框架中有一个Scope注解&#xff0c;默认的值就是singleton&#xff0c;单例的。一…...

GO语言笔记1-安装与hello world

SDK开发工具包下载 Go语言官网地址&#xff1a;golang.org&#xff0c;无法访问Golang中文社区&#xff1a;首页 - Go语言中文网 - Golang中文社区下载地址&#xff1a;Go下载 - Go语言中文网 - Golang中文社区 尽量去下载稳定版本&#xff0c;根据使用系统下载压缩包格式的安装…...

指针传参误区

C语言中指针作为形参传递时&#xff0c;func&#xff08;*a, *b&#xff09; 这种形式的话&#xff0c;是无法通过简单的 ab来修改的&#xff0c;在函数体内a的地址确实被修改成b的地址了&#xff0c;但是当函数执行结束时&#xff0c;a的地址会重新回到原本的地址里面&#xf…...

力扣-42.接雨水

题目&#xff1a; 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#xff1a;上面是由数组[0,1,0,2…...

LeetCode-移动零(283)

题目描述&#xff1a; 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 思路&#xff1a; 这里的思路跟以前做过的去重复数字的思路有点像&…...

文件系统与日志分析

一&#xff0c;文件系统 &#xff08;一&#xff09;inode 和block概述 1&#xff0c;文件数据包括元信息与实际数据 2&#xff0c;文件存储在硬盘上&#xff0c;硬盘最小存储单位是“扇区”&#xff0c;每个扇区存储512字节 3&#xff0c;block (块) 连续的八个扇区组成一…...

labview 与三菱FX 小型PLC通信(OPC)

NI OPC服务器与三菱FX3U PLC通讯方法 一、新建通道名称为&#xff1a;MIT 二、选择三菱FX系列 三、确认端口号相关的参数&#xff08;COM端&#xff1a;7.波特率&#xff1a;9600&#xff0c;数据位&#xff1a;7&#xff0c;校验&#xff1a;奇校验&#xff0c;停止位&#xf…...

掌握Linux网络配置:价格亲民,操作简便!

前言 在Linux系统中&#xff0c;网络配置是实现连接、通信和安全的重要一环。无论你是初学者还是有经验的用户&#xff0c;掌握网络配置命令能帮助你轻松管理网络接口、设置IP地址以及查看连接状态。以下是一些关键命令和示例&#xff0c;让你快速掌握网络操作的精髓&#xff…...

郑州大学算法设计与分析实验2

判断题 1 #include<bits/stdc.h> using namespace std;const int N 50; int f[N], n;int main() { // freopen("1.in", "r", stdin);ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin >> n;f[1] 1; f[2] 1;for(int i 3; i &l…...

【CMake】1. VSCode 开发环境安装与运行

CMake 示例工程代码 https://github.com/LABELNET/cmake-simple 插件 使用 VSCode 开发C项目&#xff0c;安装 CMake 插件 CMakeCMake ToolsCMake Language Support &#xff08;建议&#xff0c;语法提示) 1. 配置 CMake Language Support , Windows 配置 donet 环境 这…...

使用vue3+<script setup>+element-plus中el-table前端切片完成分页效果

<template><div><el-table :data"visibleData" :row-key"row > row.id"><el-table-column prop"name" label"姓名"></el-table-column><el-table-column prop"age" label"年龄&qu…...

vue 中 computed 和 watch 的区别

在Vue中&#xff0c;computed和watch都是用于监听数据的变化&#xff0c;并且根据变化做出相应的反应。 computed是一个计算属性&#xff0c;它会根据依赖的数据的变化自动计算得出一个新的值&#xff0c;并且具有缓存的特性。当依赖的数据发生变化时&#xff0c;computed属性…...

gephi——graphviz插件设置

gephi_graphviz插件设置 以下是我总结出来的一点经验 1. 安装graphviz软件&#xff0c;请见作者其他博客 2. 安装gephi 插件&#xff0c;并激活 3. 运行graphviz布局&#xff0c;会遇到找不到dot问题 问题描述&#xff1a;Graphviz process error X There was an error launc…...

wireshark抓包分析HTTP协议,HTTP协议执行流程,

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 使用WireShark工具抓取「HTTP协议」的数据包&#…...

Linux第13步_安装“vim编辑器”及应用介绍

学习“磁盘重新分区”后&#xff0c;嵌入式Linux系统环境搭建进入安装“vim编辑器”这个环节。vim编辑器可以用来修改文件&#xff0c;在后期使用中&#xff0c;会经常用到。 1、安装“vim编辑器” 输入“sudo apt-get install vim回车”&#xff0c;就可以执行安装“vim编辑…...

Yapi安装配置(CentOs)

环境要求 nodejs&#xff08;7.6) mongodb&#xff08;2.6&#xff09; git 准备工作 清除yum命令缓存 sudo yum clean all卸载低版本nodejs yum remove nodejs npm -y安装nodejs,获取资源,安装高版本nodejs curl -sL https://rpm.nodesource.com/setup_8.x | bash - #安装 s…...

HCIA-Datacom题库(自己整理分类的)_08_FTP协议【8道题】

一、单选 1.在使用FTP协议升级路由器软件时&#xff0c;传输模式应该选用___ 二进制模式 字节模式 文字模式 流字节模式 解析&#xff1a;二进制模式&#xff1a;在数据连接中传输&#xff0c;不对数据进行任何处理&#xff0c;不需要转换或格式化就可以传输字符。 2.以…...

【开源GPT项目 - 在问】让知识无界,智能触手可及

Chatanywhere: chatAnywhere 在问 | 让知识无界&#xff0c;智能触手可及 项目简介 这是一个免费的在线聊天工具&#xff0c;旨在让用户更方便地享受科技带来的便利。用户可以使用我们的工具来获取答案、寻求建议、进行翻译和计算等等。这是由一位个人开发者创建的&#xff…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

GitHub 趋势日报 (2025年06月06日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

多模态图像修复系统:基于深度学习的图片修复实现

多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案

在大数据时代&#xff0c;海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构&#xff0c;在处理大规模数据抓取任务时展现出强大的能力。然而&#xff0c;随着业务规模的不断扩大和数据抓取需求的日益复杂&#xff0c;传统…...

jdbc查询mysql数据库时,出现id顺序错误的情况

我在repository中的查询语句如下所示&#xff0c;即传入一个List<intager>的数据&#xff0c;返回这些id的问题列表。但是由于数据库查询时ID列表的顺序与预期不一致&#xff0c;会导致返回的id是从小到大排列的&#xff0c;但我不希望这样。 Query("SELECT NEW com…...

TCP/IP 网络编程 | 服务端 客户端的封装

设计模式 文章目录 设计模式一、socket.h 接口&#xff08;interface&#xff09;二、socket.cpp 实现&#xff08;implementation&#xff09;三、server.cpp 使用封装&#xff08;main 函数&#xff09;四、client.cpp 使用封装&#xff08;main 函数&#xff09;五、退出方法…...

数据库——redis

一、Redis 介绍 1. 概述 Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的、高性能的内存键值数据库系统&#xff0c;具有以下核心特点&#xff1a; 内存存储架构&#xff1a;数据主要存储在内存中&#xff0c;提供微秒级的读写响应 多数据结构支持&…...