计算机网络——GBN协议实现

实验目的

编程模拟实现GBN可靠传输软件

实验内容

C++ 程序模拟实现Go-Back-N可靠数据传输,需要编写一个发送端程序和一个测试端程序来模拟传输过程

具体流程

1. 编写发送端程序,调用库实现socket连接,然后主要实现滑动窗口,接收ACK确认帧和超时重传的功能
2. 编写接收端,调用监听一个端口,因为在本地实验,要模拟丢包的过程,使用随机数模拟出百分之十的丢包率。编写丢包前后不同的ACK确认帧逻辑

关键代码

发送端,先建立连接,然后接收用户在命令行的输入,获取要发送的消息和滑动窗口。然后开始按照GBN协议发送,发送完一帧后就滑动窗口往下。发送完一帧的同时还会开启一个计时器,计时器延时一秒钟,没有收到ACK就会从超时的位置开始重传

    asio::io_service io_service;
    tcp::socket socket(io_service);
    socket.connect(tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), 12345));

    std::string message;
    std::cout << "Input message: ";
    std::getline(std::cin, message);

    int window_size;
    std::cout << "Window size: ";
    std::cin >> window_size;

    std::vector<char> window(window_size);
    int base = 0;
    int next_seq_num = 0;

    asio::steady_timer timer(io_service);
    timer.expires_from_now(std::chrono::seconds(1));

    while (base < message.size()) {
        while (next_seq_num < base + window_size && next_seq_num < message.size()) {
            window[next_seq_num % window_size] = message[next_seq_num];
            char seq_num_char = static_cast<char>(next_seq_num);
            asio::write(socket, asio::buffer(&seq_num_char, 1));
            asio::write(socket, asio::buffer(&window[next_seq_num % window_size], 1)); 
            std::cout << "Seq_num: " << next_seq_num << "  Send: " << window[next_seq_num % window_size] << std::endl;
            next_seq_num++;
        }

        char ack;
        asio::async_read(socket, asio::buffer(&ack, 1), [&](const asio::error_code& error, std::size_t length) {
            if (!error) {
                for (int i = 0; i < 25; i++) {
                    std::cout << " ";
                }
                std::cout << "Receive ACK: " << static_cast<int>(ack) << std::endl;
                base = ack + 1;

                if (base == next_seq_num) {
                    timer.cancel();
                } 
                else {
                    timer.expires_from_now(std::chrono::seconds(1));
                }
            } 
            else {
                std::cout << "Error reading ACK: " << error.message() << std::endl;
            }
        });

        timer.async_wait([&](const asio::error_code& error) {
            if (!error) {
                std::cout << "Timeout resend from: " << base << std::endl;
                for (int i = base; i < next_seq_num; i++) {
                    char seq_num_char = static_cast<char>(i);
                    asio::write(socket, asio::buffer(&seq_num_char, 1));
                    asio::write(socket, asio::buffer(&window[i % window_size], 1));
                }
            }
        });

        io_service.run();
        io_service.reset();
    }

接收端,先开启端口的监听,然后开始接收消息,中间模拟随机百分之十的丢包率,如果发生丢包只会发送重复最后收到的连续的帧。还有一段处理错误的代码,接收结束消息,安全退出 

    asio::io_service io_service;
    tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 12345));

    tcp::socket socket(io_service);
    acceptor.accept(socket);

    srand(time(0));

    int expected_seq_num = -1;
    while (true) {
        char seq_num_char;
        char data;
        asio::error_code error;
        asio::read(socket, asio::buffer(&seq_num_char, 1), error);  // read sequence number
        asio::read(socket, asio::buffer(&data, 1), error);  // read data

        if (error) {
            if (error == asio::error::eof) {
                std::cout << "\nAll message have been received, connection closed" << std::endl;
            } 
            else {
                std::cout << "Error reading: " << error.message() << std::endl;
            }
            break;
        }

        int seq_num = static_cast<int>(seq_num_char);

        if (expected_seq_num == -1) {
            int random_num = rand() % 10;
            if (random_num == 0) {
                std::cout << "Loss Seq_num: " << seq_num<< std::endl;
                expected_seq_num = seq_num;
                continue;
            }
            std::cout << "Seq_num: " << seq_num << "  Receive: " << static_cast<char>(data) << std::endl;
        }
        else {
            std::cout << "Seq_num: " << seq_num << "  Receive: " << static_cast<char>(data) << std::endl;
            if (seq_num == expected_seq_num) {
                expected_seq_num = -1;
            }
            else {
                seq_num = expected_seq_num - 1;
            }
        }

        asio::write(socket, asio::buffer(&seq_num, 1));
        for (int i = 0; i < 25; i++) {
            std::cout << " ";
        }
        std::cout << "Send ACK: " << seq_num << std::endl;
    }

运行示例

因为有两个程序运行,所以我们打开两个终端。先编译链接生成发送端和接收端的程序

 先再一个终端中运行接收端,程序,监听对应的端口。然后再在另外一个终端中运行发送端程序,输入要发送的信息,和滑动窗口的大小。这里我设置的要发送的信息为“thiisatestmessage”,滑动窗口大小为5

然后程序就会开开始模拟,可以看到发送端一次性快速发送完了窗口中的内容,但是接收端在一个一个接收到只之后才会发送对应帧的ACK。可以看到我们在模拟的过程中丢失了4号和15号两个帧,这两个帧丢失后的ACK都只会重复发送丢失帧之前的最后一个ACK,然后发送端超时之后就会从对应的位置开始重新发送

完整代码

BJTU_CS_Learning/computernetwork at main · JJLi0427/BJTU_CS_Learning (github.com) 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

IDEA开启自动导包,自动删包

找到file----------->Settings选项 找到Editor-------->General------------>Auto Import选项 勾选两个选项&#xff0c;在点击Apply,在点击ok 最后就ok了

详解数据结构:栈

一、顺序栈 顺序栈的存储方式如下&#xff1a; 从图中可以看出&#xff0c;顺序栈需要两个指针&#xff0c;base指向栈底&#xff0c;top指向栈顶。 typedef struct SqStack {ElemType *base; //栈底指针ElemType *top; //栈顶指针}SqStack; 说明&#xff1a; ElemType是元…

8款不同的404页面(网站404页面必备)

第1款 部分代码 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <title>404</title><link rel"stylesheet" href"css/style.css"></head> <body><div cla…

C语言转型之路:从C到C++的类与对象初探

欢迎来CILMY23的博客 本篇主题为 C语言转型之路&#xff1a;从C到C的类与对象初探 个人主页&#xff1a;CILMY23-CSDN博客 个人专栏系列&#xff1a; Python | C语言 | 数据结构与算法 | C 感谢观看&#xff0c;支持的可以给个一键三连&#xff0c;点赞关注收藏。 写在前头…

hive搭建完整教学

目录 简介准备工作安装步骤&#xff08;一&#xff09;、下载hive包并解压到指定目录下&#xff08;二&#xff09;、设置环境变量&#xff08;三&#xff09;、下载MySQL驱动包到hive的lib目录下&#xff08;四&#xff09;、将hadoop的guava包拷贝到hive&#xff08;五&#…

美团财务科技Java后端一面:面向对象、类加载过程、全限定类名相同的类是否可以同时被加载

更多大厂面试内容可见 -> http://11come.cn 美团财务科技Java后端一面&#xff1a;面向对象、类加载过程、全限定类名相同的类是否可以同时被加载 如何理解面向对象&#xff1f; 面向对象 是具有对象概念的编程范式&#xff0c;面向对象将程序实现分为了一个个独立的对象&…

cdh cm界面HDFS爆红:不良 : 该 DataNode 当前有 1 个卷故障。 临界阈值:任意。(Linux磁盘修复)

一、表现 1.cm界面 报错卷故障 检查该节点&#xff0c;发现存储大小和其他节点不一致&#xff0c;少了一块物理磁盘 2.查看该磁盘 目录无法访问 dmesg检查发现错误 dmesg | grep error二、解决办法 移除挂载 umount /data10 #可以移除挂载盘&#xff0c;或者移除挂载目…

WPS的bug问题(解决方法->换成office吧):表格数据和透视图数据不一致问题,多次尝试确定该bug

1.软件版本 2.问题描述 我在原始表中对其中一列进行筛选&#xff0c;选择95%以上这个选项值&#xff0c;343个数据。 在筛选了95%以上这个选项之后&#xff0c;我的另一列的值全部是no&#xff0c;343个数据。 然后进行透视图之后&#xff0c;在绘制的图形中发现&#xff0c…

怎么压缩图片200k以下?压缩图片到指定大小

在工作中&#xff0c;会遇到在某些系统要上传照片&#xff0c;但是对于上传的照片大小有限制&#xff0c;比如限制大小不能超过200KB等&#xff0c;而外业拍摄的照片往往会超过限制的大小&#xff0c;那么这时就需要对照片进行压缩。尤其是我们在面对大量图片需要处理的时候&am…

一周IT资讯

又降了&#xff1f;运维4月平均月薪1W6&#xff1f; 薪资作为大部分人的主要收入来源&#xff0c;是每个人最关注的话题之一。 最近&#xff0c;小编搜索了近半年的运维薪资趋势&#xff0c;看看你的钱包缩水了没&#xff1f; *数据来自看准网 据了解&#xff0c;运维2024年…

Python 爬虫如何配置代理 IP (Py 采集)

在Python中配置代理IP&#xff0c;可以通过设置requests库的proxies参数来实现。以下是一个示例&#xff1a; import requests# 则立可以获取稳定代理Ip&#xff1a;https://www.kuaidaili.com/?refrg3jlsko0ymg # 推荐使用私密动态 IP proxies {"http": "ht…

Pulsar 社区周报 | No.2024-04-19 | Pulsar Meetup 深圳 2024 邀您报名

“ 各位热爱 Pulsar 的小伙伴们&#xff0c;Pulsar 社区周报更新啦&#xff01;这里将记录 Pulsar 社区每周的重要更新&#xff0c;周五发布。 ” Pulsar Meetup 深圳 2024 Pulsar Meetup 深圳 2024 将于 2024 年 4 月 27 日 周六举办&#xff0c;此次活动由 AscentStream 谙&a…

HR招聘测评,人才测评的方法有哪些?

各企业都需要人才&#xff0c;如果招聘不到合适的人才&#xff0c;就会对自身的发展带来极大的限制&#xff0c;很难找到自己的一席之地。一个优秀的人才&#xff0c;通常会成为许多公司争先哄抢的对象&#xff0c;在招聘过程中会成为一个香饽饽。但是要选出一个优秀的人才&…

戴尔电脑怎么关闭开机密码?

1.同时按键盘上是“window键”&#xff08;一般是键盘最下面一排第二个&#xff09;和“R键“&#xff0c;并在弹出的窗口输入“netplwiz”然后确定。 2.然后会弹出的“用户账户”窗口&#xff0c;接下来取消勾选“要使用本计算机&#xff0c;用户必须输入用户名和密码” 3.上面…

C语言---贪吃蛇(一)---准备工作

文章目录 前言1.Win32 API介绍1.1.Win32 API1.2. 控制台程序1.3.控制台屏幕上的坐标[COORD](https://learn.microsoft.com/zh-cn/windows/console/coord-str)1.4.[GetStdHandle](https://learn.microsoft.com/zh-cn/windows/console/getstdhandle)1.5.[GetConsoleCursorInfo](h…

运动想象 (MI) 分类学习系列 (9) :FBCNet

运动想象分类学习系列:FBCNet 0. 引言1. 主要贡献2. 提出的方法2.1 滤波器组卷积网络2.2 方差层结构介绍 3. 实验结果3.1 基线方法比较3.2 方差层对结果的影响3.3 脑卒中患者在相关模型中观察到更大的受试间变异性 4. 总结欢迎来稿 论文地址&#xff1a;https://arxiv.org/abs/…

详细UI色彩搭配方案分享

UI 配色是设计一个成功的用户界面的关键之一。UI 配色需要考虑品牌标志、用户感受、应用程序的使用场景&#xff0c;这样可以帮助你创建一个有吸引力、易于使用的应用程序。本文将分享 UI 配色的相关知识&#xff0c;帮助设计师快速构建 UI 配色方案&#xff0c;以满足企业的需…

什么是IoT?

什么是IoT&#xff1f; IoT&#xff0c;即物联网&#xff08;Internet of Things&#xff09;&#xff0c;是通过信息传感设备和互联网将各种物品连接起来&#xff0c;实现智能化的识别、定位、跟踪、监控和管理的网络系统。 以下是关于IOT的一些详细解释&#xff1a; 基本概…

【RAG 论文】面向知识库检索进行大模型增强的框架 —— KnowledGPT

论文&#xff1a;KnowledGPT: Enhancing Large Language Models with Retrieval and Storage Access on Knowledge Bases ⭐⭐⭐⭐ 复旦肖仰华团队工作 论文速读 KnowledGPT 提出了一个通过检索知识库来增强大模型生成的 RAG 框架。 在知识库中&#xff0c;存储着三类形式的知…

记录一下flume中因为taildir_position.json因位置不对导致数据无法从kafka被采到hdfs上的问题

【背景说明】 我需要用flume将kafka上的数据采集到hdfs上&#xff0c;发现数据怎么到不了hdfs。 【问题排查】 1.kafka上已有相应的数据 2.我的flume配置文档&#xff08;没问题&#xff09;&#xff0c; 3.时间拦截器&#xff08;没问题&#xff09;&#xff0c; 4.JSONObje…
最新文章