滑动窗口协议仿真(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.题目描述 滑动窗口协议以基于分组的数据传输协议为特征,该协议适用于在数据链路层以及传输层中对按 顺序传送分组的可靠性要求较高的环境。在长管道传输过程(特别是无线环境)中,相应的滑动窗口 协议可实现高效的重传恢复。附录 …...
uniapp上传文件时用到的api是什么?格式是什么?
在UniApp中,你可以使用uni.uploadFile()方法来上传文件。这是一个异步方法,用于将本地资源上传到服务器。 该方法的基本格式如下: uni.uploadFile({url: 上传接口地址,filePath: 要上传的文件路径,name: 后端接收的文件参数名,formData: {/…...

Java面试——框架篇
1、Spring框架中的单例bean是线程安全的吗? 所谓单例就是所有的请求都用一个对象来处理,而多例则指每个请求用一个新的对象来处理。 结论:线程不安全。 Spring框架中有一个Scope注解,默认的值就是singleton,单例的。一…...

GO语言笔记1-安装与hello world
SDK开发工具包下载 Go语言官网地址:golang.org,无法访问Golang中文社区:首页 - Go语言中文网 - Golang中文社区下载地址:Go下载 - Go语言中文网 - Golang中文社区 尽量去下载稳定版本,根据使用系统下载压缩包格式的安装…...

指针传参误区
C语言中指针作为形参传递时,func(*a, *b) 这种形式的话,是无法通过简单的 ab来修改的,在函数体内a的地址确实被修改成b的地址了,但是当函数执行结束时,a的地址会重新回到原本的地址里面…...
力扣-42.接雨水
题目: 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 示例 1: 输入:height [0,1,0,2,1,0,1,3,2,1,2,1] 输出:6 解释:上面是由数组[0,1,0,2…...

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

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

labview 与三菱FX 小型PLC通信(OPC)
NI OPC服务器与三菱FX3U PLC通讯方法 一、新建通道名称为:MIT 二、选择三菱FX系列 三、确认端口号相关的参数(COM端:7.波特率:9600,数据位:7,校验:奇校验,停止位…...
掌握Linux网络配置:价格亲民,操作简便!
前言 在Linux系统中,网络配置是实现连接、通信和安全的重要一环。无论你是初学者还是有经验的用户,掌握网络配置命令能帮助你轻松管理网络接口、设置IP地址以及查看连接状态。以下是一些关键命令和示例,让你快速掌握网络操作的精髓ÿ…...

郑州大学算法设计与分析实验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项目,安装 CMake 插件 CMakeCMake ToolsCMake Language Support (建议,语法提示) 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中,computed和watch都是用于监听数据的变化,并且根据变化做出相应的反应。 computed是一个计算属性,它会根据依赖的数据的变化自动计算得出一个新的值,并且具有缓存的特性。当依赖的数据发生变化时,computed属性…...

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

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

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

Yapi安装配置(CentOs)
环境要求 nodejs(7.6) mongodb(2.6) 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协议升级路由器软件时,传输模式应该选用___ 二进制模式 字节模式 文字模式 流字节模式 解析:二进制模式:在数据连接中传输,不对数据进行任何处理,不需要转换或格式化就可以传输字符。 2.以…...

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

通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...

现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...

在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...

排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
提升移动端网页调试效率:WebDebugX 与常见工具组合实践
在日常移动端开发中,网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时,开发者迫切需要一套高效、可靠且跨平台的调试方案。过去,我们或多或少使用过 Chrome DevTools、Remote Debug…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...