Qt实现Kermit协议(三)

3 实现

3.2 KermitSendFile

该模块实现了Kermit发送文件功能。

序列图如下:
序列图

3.2.1 KermitSendFile定义

class QSerialPort;
class KermitSendFile : public QObject, public Kermit
{Q_OBJECT
public:explicit KermitSendFile(QSerialPort *serial, QObject *parent = nullptr);
public slots:void start(QString const& fileName);void stop();void cancel();signals:void gotFileSize(quint64 filesize);void progressInfo(quint32 blockNumber, quint64 bytesOfSend);void error(QString const& e);void finished();protected:int write(char const *data, int size) override;int read(char *data, int size) override;char getc() override;void on_ack(int seq, const char* data, int size) override;void on_nack(int seq, const char* data, int size) override;void on_error(int seq, const char* data, int size) override;
private:void send_data(int seq);int next_seq(int seq) { return (seq + 1) % 64; }bool singled() { return signal_; }void doSignal() { signal_ = true; };bool getchar(char & ch);
private:QSerialPort* serial_;volatile bool signal_;State state_ = SSNUL;QFile file_;int timeMs = 0;quint32 blockNumber = 0;quint64 bytesOfSend_ = 0;
};

公共接口:

  • start 开始发送文件
  • stop 停止传输文件
  • cancel 中断传输文件

信号:

  • gotFileSize 文件大小信号
  • progressInfo 传输进度信号
  • error 出错信号
  • finished 传输结束信号

重载接口:

  • on_ack 处理应答包
  • on_nack 处理否定应答包
  • on_error 处理错误包
  • write 向串口写数据
  • read 从串口读数据
  • getc 从串口读取一个字符

其它接口:

  • send_data 从文件读取数据编码并发送

3.2.2 KermitSendFile实现

3.2.2.1 start/stop/cancel
void KermitSendFile::start(QString const& fileName)
{QFileInfo fileInfo(fileName);emit gotFileSize(fileInfo.size());send_init();state_ = SSINT;file_.setFileName(fileName);while(!singled() && state_ != SSBRK)recv_packet();emit finished();serial_->moveToThread(QApplication::instance()->thread());
}void KermitSendFile::stop() { doSignal(); }void KermitSendFile::cancel() { state_ = SSBRK; }

函数说明:

  • start
    • 发送文件大小信号
    • 发送开始传输包
    • 循环接收数据包,知道收到停止或终止信号
  • stop 发送停止信号
  • cancel 设置终止信号
3.2.2.2 on_ack/on_nack/on_error
void KermitSendFile::on_ack(int seq, const char* data, int size)
{if(seq == 0 && state_ == SSINT){state_ = SSDAT;file_.open(QIODevice::ReadOnly);Kermit::on_ack(seq, data, size);}if(state_ == SSEND) {state_ = SSBRK;return;}if(!file_.atEnd())send_data(next_seq(seq));else{send_break(next_seq(seq));state_ = SSEND;}
}void KermitSendFile::on_nack(int seq, const char* data, int size)
{if(state_ == SSDAT)resend();Kermit::on_nack(seq, data, size);
}void KermitSendFile::on_error(int seq, const char* data, int size)
{emit error(QString::fromStdString(data, size));Kermit::on_error(seq, data, size);
}

函数说明:

  • on_ack
    • 如果是第一个包,打开文件并调用父类on_ack来处理包
    • 如果状态是结束则退出
    • 如果文件没有发送完,则发送数据,发送完毕则设置状态为结束
  • on_nack 如果是在收发数据状态,则重传
  • on_error 发送出错信号
3.2.2.3 write/read/getc/send_data
int KermitSendFile::write(char const *data, int size) {return serial_->write(data, size);
}int KermitSendFile::read(char *data, int size)
{int read_size = 0;while(!singled() && read_size < size){if(serial_->waitForReadyRead(timeMs))read_size += serial_->read(data + read_size, size - read_size);}return read_size;
}char KermitSendFile::getc()
{char c = NUL;while(!singled()){if(serial_->waitForReadyRead(timeMs)){serial_->getChar(&c);break;}}return c;
}void KermitSendFile::send_data(int seq)
{char data[MaxLen];//94 93int size = 0;int readSize = 0;char c;while(!singled() && size < MaxLen - 1){if(!getchar(c))break;size += encode(c, data + size);readSize++;}if(size > 0){Kermit::send_data(seq, data, size);blockNumber++;bytesOfSend_ += readSize;emit progressInfo(blockNumber, bytesOfSend_);}
}

函数说明:

  • write 向串口写数据
  • read 从串口读取指定大小数据
  • getc 从串口读取一个字符
  • send_data
    • 从文件读取指定数据并编码
    • 发送数据并发送进度信号

Qt实现Kermit协议(二)  Qt实现Kermit协议(三)

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

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

相关文章

【竞技宝jjb.lol】LOL:LPL春季常规赛荣誉评选出炉!

北京时间2024年4月3日,英雄联盟LPL2024春季季后赛正在如火如荼的进行之中,常规赛阶段的荣誉评选结果在近日出炉,除三个最佳阵容之外,其中BLG战队的中单选手knight斩获春季赛常规赛MVP,而FPX战队的打野选手milkway则拿到春季赛常规赛的最佳新秀。 春季常规赛最有价值选手:BLG.kn…

HAL STM32 硬件I2C方式读取AS5600磁编码器获取角度例程

HAL STM32 硬件I2C方式读取AS5600磁编码器获取角度例程 &#x1f4cd;相关篇《STM32 软件I2C方式读取AS5600磁编码器获取角度例程》 ✨stm32使用硬件I2C去读取角度数据&#xff0c;通过STM32CubeMX工具配置工程&#xff0c;读取角度数据&#xff0c;只需要调用一个函数&#xf…

【学习】渗透测试有哪些重要性

随着信息技术的迅猛发展&#xff0c;网络安全问题日益凸显。渗透测试作为网络安全防御的重要手段之一&#xff0c;旨在模拟黑客攻击&#xff0c;发现并修复潜在的安全漏洞&#xff0c;提高网络系统的安全性。本文将介绍渗透测试的概念、重要性、实施步骤及实践案例&#xff0c;…

[蓝桥杯练习题]出差

一道DJ题,重要的是隔离时间,把隔离时间加在边权上即可 现实生活的题大多都是无向图建图,需要边的两端点各自上邻接表和相同权重 #include<bits/stdc.h> using namespace std; #define ll long long const int N1005; const int M10005; struct edge{int to;ll w;edge(int…

Monaco Editor系列(二)Hello World 初体验

前言&#xff1a;上一篇文章我主要分享了从 Monaco Editor 入口文件以及官方提供的示例项目入手&#xff0c;对一部分源码进行剖析&#xff0c;以及分享了初始化阶段代码的大致执行步骤&#xff0c;这一篇了来讲一下我们要用 Monaco Editor 的时候该怎么用。其中会涉及到一些 A…

LeetCode 热题 100 | 动态规划(一)

目录 1 70. 爬楼梯 1.1 基本思路 1.2 官方题解 2 118. 杨辉三角 3 198. 打家劫舍 菜鸟做题&#xff0c;语言是 C 1 70. 爬楼梯 核心思想&#xff1a;把总问题拆解为若干子问题。 总问题&#xff1a;上到 5 楼的方式有多少种子问题&#xff1a;上到 4 楼的方式有多…

炫我科技:云渲染领域的佼佼者

随着数字化时代的来临&#xff0c;云渲染技术正逐渐成为影视、游戏、动画等创意产业的重要支柱。在这一领域中&#xff0c;炫我科技凭借其卓越的技术实力、优质的服务以及不断创新的精神&#xff0c;已然成为了云渲染行业的佼佼者。 炫我科技自成立之初&#xff0c;便以打造高…

SV学习笔记(二)

接口 什么是接口&#xff1f; 接口 主要用作验证 &#xff0c;国外有些团队会使用sv进行设计&#xff0c;那么接口就会用作设计。验证环境中&#xff0c;接口可以 使连接变得简洁而不易出错 。interface和module的使用性质很像&#xff0c; 可以定义端口&#xff0c;也可以定…

基于单片机的炉温控制系统设计

**单片机设计介绍&#xff0c;基于单片机的炉温控制系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的炉温控制系统设计是一个融合了单片机技术、温度传感技术、控制算法以及硬件电路设计等多个领域的综合性项…

在ChatGPT中,能用DALL·E 3编辑图片啦!

4月3日&#xff0c;OpenAI开始向部分用户&#xff0c;提供在ChatGPT中的DALLE 3图片编辑功能。 DALLE 3是OpenAI在2023年9月20日发布的一款文生图模型&#xff0c;其生成的图片效果可以与Midjourney、leonardo、ideogram等顶级产品媲美&#xff0c;随后被融合到ChatGPT中增强其…

【BlossomConfig】SpringCloud项目是如何对bootstrap配置文件进行加载的?

文章目录 bootstrap配置文件的读取什么是配置中心&#xff1f;以及如何实现一个配置中心&#xff1f;SpringBoot如何实现配置的管控&#xff1f;SpringCloud项目是如何对bootstrap配置文件进行加载的&#xff1f;Nacos是如何实现配置文件的读取加载的&#xff1f;开发配置中心前…

一次普通的漏洞挖掘思路分享

No.0 前言 一名web安全小白&#xff0c;自己仅学了一点思路&#xff0c;直接实战&#xff0c;运气不错&#xff0c;碰到了管理员弱口令&#xff0c;进入后台后&#xff0c;继续测试自己学会的思路挖掘深一点的漏洞&#xff0c;这里与各位分享一下&#xff0c;如果有更多的思路…