Qt实现Kermit协议(四)

news2024/11/17 8:35:32

3 实现

3.3 KermitRecvFile

该模块实现了Kermit接收文件功能。

序列图如下:
序列图

3.3.1 KermitRecvFile定义

class QSerialPort;
class KermitRecvFile : public QObject, public Kermit
{
    Q_OBJECT
public:
    explicit KermitRecvFile(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_init(int seq, const char* data, int size) override;
    void on_data(int seq, const char* data, int size) override;
    void on_break(int seq, const char* data, int size) override;
private:
    void saveData(const char* data, int size);
    bool singled() { return signal_; }
    void doSignal() { signal_ = true; };
private:
     QSerialPort* serial_;
     volatile bool signal_;
     State state_ = SSNUL;
     QFile file_;
     int timeMs = 0;
     quint32 blockNumber = 0;
     quint64 bytesOfRecv_ = 0;

};

公共接口:

  • start 开始接收文件
  • stop 停止传输文件
  • cancel 中断传输文件

信号:

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

重载接口:

  • on_init 处理开始包
  • on_data 处理数据包
  • on_break 处理中断包
  • write 向串口写数据
  • read 从串口读数据
  • getc 从串口读取一个字符

其它接口:

  • saveData 解码数据并保存

3.3.2 KermitRecvFile实现

3.3.2.1 start/stop/cancel
void KermitRecvFile::start(QString const& fileName)
{
    file_.setFileName(fileName);
    while(!singled() && state_ != SSBRK)
        recv_packet();
    emit finished();
    serial_->moveToThread(QApplication::instance()->thread());
}

void KermitRecvFile::stop() { doSignal(); }

void KermitRecvFile::cancel() { state_ = SSBRK; }

函数说明:

  • start
    • 循环接收数据包,直到收到停止或终止信号
    • 发送结束信号
  • stop 发送停止信号
  • cancel 设置终止信号
3.3.2.2 on_init/on_data/on_break
void KermitRecvFile::on_init(int seq, const char* data, int size)
{
    Kermit::on_init(seq, data, size);
    state_ = SSINT;
}

void KermitRecvFile::on_data(int seq, const char* data, int size)
{
    Q_UNUSED(seq)
    if(state_ == SSINT)
    {
        file_.open(QIODevice::WriteOnly);
        state_ = SSDAT;
    }
    if(file_.isOpen())
    {
        saveData(data, size);
        send_ack(seq);
    }
}

void KermitRecvFile::on_break(int seq, const char* data, int size)
{
    Q_UNUSED(seq)
    Q_UNUSED(data)
    Q_UNUSED(size)

    state_ = SSBRK;
}

函数说明:

  • on_init 处理开始包,设置状态为初始
  • on_data
    • 如果是初始状态,则打开文件,将状态设置为接收数据状态
    • 保存数据
  • on_break 设置状态为中断
3.2.2.3 write/read/getc/saveData
int KermitRecvFile::write(char const *data, int size) {
    return serial_->write(data, size);
}

int KermitRecvFile::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 KermitRecvFile::getc()
{
    char c = NUL;
    while(!singled())
    {
        if(serial_->waitForReadyRead(timeMs))
        {
            serial_->getChar(&c);
            break;
        }
    }
    return c;
}

void KermitRecvFile::saveData(const char* data, int size)
{
    char d[MaxLen];
    char a;
    int index = 0;
    int recvSize = 0;

    while(index < size)
    {
        index += decode(data + index, a);
        d[recvSize++] = a;
    }

    file_.write(d, recvSize);

    blockNumber++;
    bytesOfRecv_ += recvSize;
    emit progressInfo(blockNumber, bytesOfRecv_);
}

函数说明:

  • write 向串口写数据
  • read 从串口读取指定大小数据
  • getc 从串口读取一个字符
  • saveData
    • 解码数据
    • 保存数据
    • 发送进度信号

Qt实现Kermit协议(三)
未完待续…

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

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

相关文章

【SCI绘图】【小提琴系列1 python】绘制按分类变量分组的垂直小提琴图

SCI&#xff0c;CCF&#xff0c;EI及核心期刊绘图宝典&#xff0c;爆款持续更新&#xff0c;助力科研&#xff01; 本期分享&#xff1a; 【SCI绘图】【小提琴系列1 python】绘制按分类变量分组的垂直小提琴图&#xff0c;文末附完整代码 小提琴图是一种常用的数据可视化工具…

YUM仓库和编译安装

目录 一.YUM仓库搭建 1.简介&#xff1a; 2.搭建思路&#xff1a; 3.实验&#xff1a;单机yum的创建 二.编译安装 1.简介 2.安装过程 3.实验&#xff1a;编译安装nginx 一.YUM仓库搭建 1.简介&#xff1a; yum是一个基于RPM包&#xff08;是Red-Hat Package Manager红…

深度学习500问——Chapter06: 循环神经网络(RNN)(3)

文章目录 6.11 LSTM 6.11.1 LSTM的产生原因 6.11.2 图解标准RNN和LSTM的区别 6.11.3 LSTM核心思想图解 6.11.4 LSTM流行的变体 6.12 LSTMs与GRUs的区别 6.13 RNNs在NLP中的典型应用 6.11 LSTM 6.11.1 LSTM的产生原因 RNN在处理长期依赖&#xff08;时间序列上距离较远的…

DC电源模块在电子设备中的应用场景

BOSHIDA DC电源模块在电子设备中的应用场景 DC电源模块在电子设备中广泛应用于以下场景&#xff1a; 1. 电子产品&#xff1a;如手机、平板电脑、笔记本电脑等便携式设备&#xff0c;这些设备通常需要稳定的直流电源来供电。 2. 工业设备&#xff1a;包括自动化设备、工业机器…

【绘图案例-绘制图片 Objective-C语言】

一、绘制图片 1.接下来,我们来说这个绘制图片啊,把之前的copy代码复制粘贴一份儿,名字改成“05-绘制图片”, 1)首先:绘制图片,你要有图片,思路都是一样的,你绘制啥,首先要有啥, 素材里边,我们来说一下啊,这个里边儿,主要来说一下,小图、和、大图、的区别, 然后…

通过 Cookie、Redis共享Session 和 Spring 拦截器技术,实现对用户登录状态的持有和清理(四)

本篇内容对应 “2.5 开发登录、退出功能” 小节 “4.7 优化登陆模块” 小节 2.6 显示登录信息 2.7 账号设置 2.8 检查登录状态 登录功能的流程是什么&#xff1f; UUID为什么不会重复&#xff1f; 因为UUID是基于mac物理地址、时间戳、随机数等信息生成。因此UUID居于极高的唯…

太阳能光伏电子实验酸洗用PFA方槽耐受强酸碱耐高温

PFA清洗槽是四氟清洗桶后的升级款&#xff0c;主要用于半导体光伏光电等行业&#xff0c;一体成型&#xff0c;无需担心漏液&#xff0c;表面光滑无毛刺。 别名PFA浸泡桶、PFA酸缸、PFA方槽等&#xff0c;可定制尺寸&#xff0c;可配套盖子&#xff0c;盖子有PFA/PTFE两种材质…

智过网:一建继续教育,操作指南与周期解析

随着社会的快速发展和技术的不断更新&#xff0c;建筑行业对从业人员的专业素质要求也在逐步提高。为了确保一级建造师的专业技能能够与时俱进&#xff0c;满足行业发展的需求&#xff0c;继续教育成为了必不可少的环节。本文将详细解析一建继续教育的操作流程及其周期安排&…

Hugging Face入门(一)

简介 本文主要内容&#xff1a; Hugging Face介绍环境搭建敲两个例子 Hugging Face介绍 Hugging Face 是一家法美合资公司&#xff0c;总部位于纽约市&#xff0c;成立于2016年。它由法国企业家Clment Delangue、Julien Chaumond和Thomas Wolf在纽约市创立&#xff0c;最初是…

让智能体像孩子一样观察别人学习动作,跨视角技能学习数据集EgoExoLearn来了

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 新建了免费的人工智能中文站https://ai.weoknow.com 新建了收费的人工智能中文站https://ai.hzytsoft.cn/ 更多资源欢迎关注 在探索人工智能边界时&#xff0c;我们时常惊叹于人类孩童的学习能力 —— 可以轻易地将他人…

基于SpringBoot的高校自习室预约系统

基于SpringBoot的高校自习室预约系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatis工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统功能分析 本次的功能设计主要围绕着学生和管理员两个角色&#xff0c;对于学生的用…

AI预测福彩3D第29弹【2024年4月7日预测--第7套算法重新开始计算第2次测试】

今天咱们继续进行进行第7套算法的测试&#xff0c;今天是第2次测试&#xff0c;昨天已经成功命中&#xff0c;其中7码大方案全部命中&#xff0c;四码小方案也命中。再接再厉&#xff0c;继续验证&#xff0c;废话不多说&#xff0c;直接上图上结果~ 2024年4月7日3D的七码预测结…

集合容器面试题

Java 容器都有哪些&#xff1f; Java 容器分为 Collection 和 Map 两大类 Collection 和 Collections 有什么区别&#xff1f; Collection 是一个集合接口&#xff0c;它提供了对集合对象进行基本操作的通用接口方法&#xff0c;所有集合都是它的子类&#xff0c;比如 List、…

电商卖家如何从1688批量采集商品信息并铺货到自己店铺?

目前&#xff0c;各大电商平台严查无货源&#xff0c;不管是已经开店还是准备开店的卖家&#xff0c;想要店铺长久发展&#xff0c;都需要从1688找授权分销的厂家拿货源铺货。 然而很多新手卖家在1688找货源时&#xff0c;不知道如何找到物美价廉的源头厂货&#xff0c;选好货…

SpringBoot实现RabbitMQ的通配符交换机(SpringAMQP 实现Topic交换机)

文章目录 pomyml生产者消费者 Topic类型的Exchange与Direct相比&#xff0c;都是可以根据RoutingKey把消息路由到不同的队列。只不过Topic类型Exchange可以让队列在绑定Routing key 的时候使用通配符&#xff01; Routingkey 一般都是有一个或多个单词组成&#xff0c;多个单词…

关于Linux下的进程创建与终止(进程篇 - 涉及写时拷贝,fork函数)

目录 创建进程 写时拷贝 fork函数 进程终止 进程终止时&#xff0c;操作系统都做了什么&#xff1f; 进程终止的常见方式有哪些&#xff1f; 如何使用代码终止掉一个进程&#xff1f; 创建进程 写时拷贝 在了解下面的内容之前&#xff0c;我们需要先聊一聊写时拷贝这一…

MySQL-基本SQL语句编写:运算符练习

运算符练习 1.选择工资不在5000到12000的员工的姓名和工资 SELECT last_name,salary FROM employees #where salary not between 5000 and 12000; WHERE salary < 5000 OR salary > 12000;2.选择在20或50号部门工作的员工姓名和部门号 SELECT last_name,department_id…

ChatGPT 之联盟营销

原文&#xff1a;ChatGPT for Affiliate Marketing 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 第二章 制定转化对话 制定转化对话是每个营销人员和企业所有者都应该掌握的关键技能。它涉及创建和传递引人入胜的信息&#xff0c;吸引您的受众并激励他们采取行动。…

【windows】--- nginx 超详细安装并配置教程

目录 一、下载 nginx二、安装三、查看是否安装成功四、配置五、关闭 nginx六 负载均衡七 配置静态资源1. 根目录下的子目录(root)2.完全匹配(alias) 刷新配置&#xff08;不必重启nginx&#xff09;八、后端鉴权 一、下载 nginx 打开 nginx 的官网&#xff1a;nginx.org/ &…

【操作系统】STM32-操作系统——持续更新

【操作系统】STM32-操作系统——持续更新 文章目录 前言一、ucosii二、freertos1.介绍2.移植 总结 前言 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、ucosii UCOSII移植到STM32F103C8T6上之移植记录&#xff08;一&#xff09; UCOSII移植到ST…