滑动窗口协议仿真(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博客

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/602684.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

编程笔记 html5cssjs 019 HTML实体

编程笔记 html5&css&js 019 HTML实体 一、HTML 字符实体二、HTML 符号实体小结 在HTML文档中&#xff0c;用一些标记表示特定的格式&#xff0c;那我们想使用这些标记字符本身时就出了问题&#xff0c;直接使用时&#xff0c;会被浏览器解析为标记的&#xff0c;要想显…

UnityVR入门之六 如何让3DUI层级在场景模型之上

一、问题来源 根据 UnityVR入门之五 射线检测交互-CSDN博客 这一章节我们了解到VR要与UI交互需要将Canvas设置为World Space属性&#xff0c;然后使用碰撞盒的方式进行射线交互。 正常我们ui是始终叠加在3d场景之上的&#xff0c;如此设置当ui与场景模型相交就会遮挡穿模 二、解…

Java爬虫获取省市区镇村5级行政区划

公司有个项目需要五级行政区划&#xff0c;没有现成的数据&#xff0c;写了一段代码&#xff0c;从gj统计j获取的数据。记录一下。 1.引入maven解析html <!-- jsoup --> <dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifa…

Liunx JBK、Python安装和SSH免密登陆

一. JBK的安装 https://www.cnblogs.com/javabg/p/10332993.html 1.查找java相关的列表&#xff1a; yum -y list java* 或 yum search jdk 2.安装JBK&#xff1a; yum install java-11-openjdk.x86_64 yum install java-11-openjdk-devel.x86_64 3.完成安装后验…

Spring+Vue实战项目环境准备跑通程序

SpringVue 源项目 后端&#xff1a; 首先在GitHub上克隆项目到本地&#xff08;zip包下载/sourcetree拉取/gitbash克隆&#xff09;。 https://github.com/songboriceman/doubao_community_backend 然后下载Lombok安装到你的IDE&#xff08;eclipse&#xff09;。 https://p…

2022年多元统计分析期末试题

2023年多元统计分析期末试题 1.试论述系统聚类、动态聚类和有序聚类的异同之处。 2、设 X {X} X~ N 3 {N_3} N3​(μ&#xff0c;Σ)&#xff0c;其中 X {X} X ~ ( X 1 {X_1} X1​, X 2 {X_2} X2​, X 3 {X_3} X3​)&#xff0c;μ (1,-2,3)‘&#xff0c;Σ [ 1 1 1 1 3 2…

ThinkPHP5多小区物业管理系统源码(支持多小区)

基于 ThinkPHP5 Bootstrap 倾力打造的多小区物业 管理系统源码&#xff0c;操作简单&#xff0c;功能完善&#xff0c;用户体验良好 开发环境PHP7mysql 安装步骤: 1.新建数据库db_estate,还原数据db_estate.sql 2.修改配置文件&#xff1a;application/database.php 3.运…

《C++语言程序设计(第5版)》(清华大学出版社,郑莉 董渊编著)习题——第2章 C++语言简单程序设计

2-15 编写一个程序&#xff0c;运行时提示输入一个数字&#xff0c;再把这个数字显示出来。 #include <iostream>using namespace std;int main() {// 提示用户输入数字cout << "请输入一个数字: ";// 用于存储用户输入的数字的变量double number;// 从…

FineBI实战(2):案例架构说明及数据准备

1 系统架构 基于MySQL搭建数据仓库基于Kettle进行数据处理帆软FineBI基于MySQL搭建的数据仓库进行数据分析 2 数据流程图 通过Kettle将MySQL业务系统数据库中&#xff0c;将数据抽取出来&#xff0c;然后装载到MySQL数据仓库中。编写SQL脚本&#xff0c;对MySQL数据仓库中的数…

LeetCode 2807. 在链表中插入最大公约数【链表,迭代,递归】1279

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

XXL-JOB学习笔记-新增企业微信告警通知

xxl-job默认的告警通知方式是发送邮件&#xff0c;工作中不易及时的收到通知并作出响应&#xff0c;所以想要调整下告警的通知方式&#xff0c;查阅文档资料&#xff0c;发现可以扩展xxl-job的源码实现支持。 主要思路就是根据xxl-job现有的告警机制&#xff0c;扩展实现企业微…

浅谈Java 微服务技术:理论与实践

目录 1. 引言 2. 什么是微服务架构&#xff1f; 2.2 微服务的优势 3. 微服务架构的设计原则 3.1 单一职责原则 3.2 服务自治原则 3.3 去中心化原则 4. 微服务通信方式 4.1 RESTful API 4.2 消息队列 5. 服务注册与发现 6. 微服务容器化与Docker 7. 微服务监控与日志…

SQL注入总结

又到了期末时间段&#xff0c;此文章是自己总结所学&#xff0c;仅供参考。 目录&#xff1a; 一、原理 一般流程 二、分类 按照请求分类 盲注分类 按照头部字段 其他类型 三、防御 代码层面 网络层面 一、原理&#xff1a; 后端web服务器对用户输入的恶意字符过滤不严&am…

数据结构和算法-交换排序中的快速排序(演示过程 算法实现 算法效率 稳定性)

文章目录 总览快速排序&#xff08;超级重要&#xff09;啥是快速排序演示过程算法实现第一次quicksort函数第一次partion函数到第一次quicksort的第一个quicksort到第二次quicksort的第一个quicksort到第二次quicksort的第二个quicksort到第一次quicksort的第二个quicksort到第…

Java反射和动态代理

文章目录 1、反射1.1 反射的概述1.2 反射作用1.3 获取字节码文件对象的方式1.4 字节码文件和字节码文件对象1.5 获取构造方法1.6 获取构造方法并创建对象1.7 获取成员变量并获取值和修改值1.8 获取成员方法1.9 获取成员方法并运行1.10 反射练习1.10.1 泛型擦除1.10.2 修改字符串…

uniapp 创建组件组件

组件&#xff1a;用于将某个功能的 HTML、CSS、JS 封装到一个文件中&#xff0c;提高代码的复用性和可维护性。 创建组件 一、在根目录中创建 components 文件夹&#xff0c;右键点击新建组件。 二、输入组件名称、选择默认模板、点击创建组件。 三、在组件中正常编写内容即可…

动态编译 - Dynamically Compile and Load External Java Classes

文章目录 概述Code 概述 动态编译和加载外部Java类的核心流程可以概括为以下几个步骤&#xff1a; 读取源代码: 首先&#xff0c;需要获取到外部的Java源代码。这通常是通过读取文件、网络资源或者数据库中的源代码字符串来实现的。编译源代码: 接下来&#xff0c;需要使用Ja…

计算机网络(8):因特网上的音频/视频服务

概述 计算机网络最初是为传送数据设计的。因特网 IP 层提供的 “尽最大努力交付” 服务以及每一个分组独立交付的策略&#xff0c;对传送数据信息十分合适。因特网使用的 TCP 协议可以很好地解决P层不能提供可靠交付这一问题。 音频/视频常称为多媒体信息 多媒体信息&#xff…

unity 安卓 TCP可以连接别人,但是作为服务器无法被连接

现象非常的奇特&#xff0c;电脑ping手机没问题&#xff0c;用手机的socket调试助手也没问题&#xff0c;手机还能向外连接tcp服务器&#xff0c;但是电脑连手机tcp服务器连不上。更有趣的是&#xff0c;有些手机做tcp服务器可以被连接&#xff0c;有些手机做tcp服务器不能被连…

容器相关笔记

1.容器 1.什么是容器 容器就是存放对象的集合 2.java中的容器 容器就是一系列的类或接口&#xff0c;用来存储一系列对象的地址 3.容器里存放的是引用数据类型&#xff08;存对象的地址&#xff0c;不是对象本身&#xff09;&#xff0c;不能存基本数据类型 4.容器存放的两种格…