Qt实现Kermit协议(四)

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协议(三)
未完待续…

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

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

相关文章

drissionpage设置无头模式new模式

最近朋友介绍&#xff0c;所以在使用drissionpage调试项目。 写代码的时候是在有脸模式写的&#xff0c;一切正常。 但是一旦切换打无头模式&#xff0c;报错&#xff0c;找不到元素什么的。 开始以为是我的元素查找报错&#xff0c;后面用了截图发现&#xff0c;无头模式被…

银河麒麟操作系统Kylin Linux 离线安装Nginx1.21.5

一、查看操作系统版本号 nkvers ############## Kylin Linux Version ################# Release: Kylin Linux Advanced Server release V10 (Lance)Kernel: 4.19.90-52.15.v2207.ky10.x86_64Build: Kylin Linux Advanced Server release V10 (SP3) /(Lance)-x86_64-Build20/…

python怎么处理txt

导入文件处理模块 import os 检测路径是否存在&#xff0c;存在则返回True&#xff0c;不存在则返回False os.path.exists("demo.txt") 如果你要创建一个文件并要写入内容 #如果demo.txt文件存在则会覆盖&#xff0c;并且demo.txt文件里面的内容被清空&#xff0c;如…

HarmonyOS NEXT应用开发案例——阻塞事件冒泡

介绍 本示例主要介绍在点击事件中&#xff0c;子组件enabled属性设置为false的时候&#xff0c;如何解决点击子组件模块区域会触发父组件的点击事件问题&#xff1b;以及触摸事件中当子组件触发触摸事件的时候&#xff0c;父组件如果设置触摸事件的话&#xff0c;如何解决父组…

输油管道变电所运维系统发展趋势

摘要&#xff1a;随着现代化技术以及信息化手段的飞速发展&#xff0c;社会已经进入到了全新的发展阶段&#xff0c;这也为自动化技术的发展起到了良好的促进作用&#xff0c;特别是在目前输油管道电网快速发展的背景下&#xff0c;传统的输油管道变电站管理模式与管理系统&…

单元测试——Junit (断言、常用注解)

单元测试 Junit单元测试框架 使用 断言测试 使用Assert.assertEquals(message, 预期值, 实际值); 这段代码是用于在测试中验证某个方法的返回值是否符合预期。其中&#xff0c;"方法内部有bug"是用于在断言失败时显示的提示信息。4是预期的返回值&#xff0c;index…

云原生(七)、Kubernetes初学 + 裸机搭建k8s集群

Kubernetes简介 Kubernetes&#xff08;通常简称为K8s&#xff09;是一个开源的容器编排平台&#xff0c;最初由Google设计和开发&#xff0c;现在由Cloud Native Computing Foundation&#xff08;CNCF&#xff09;维护。它旨在简化容器化应用程序的部署、扩展和管理。 Kube…

ConcurrentHashMap线程安全机制

put源码&#xff1a; public V put(K key, V value) {return putVal(key, value, false); }/** Implementation for put and putIfAbsent */ final V putVal(K key, V value, boolean onlyIfAbsent) {if (key null || value null) throw new NullPointerException();int has…

python爬虫----了解爬虫(十一天)

&#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; &#x1f388;&#x1f388;所属专栏&#xff1a;python爬虫学习&#x1f388;&#x1f388; ✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天…

Qt元对象系统

第二章Qt元对象系统 文章目录 第二章Qt元对象系统1.什么是元对象&#xff1f;2.元对象系统组成3.信号与槽信号和槽的本质绑定信号与槽自定义槽定义槽函数必须遵循一下规则槽函数的类型自定义槽案例 自定义信号自定义信号需要遵循以下规则信号和槽重载二义性问题 4.内存管理1. 简…

PFA(可溶性聚四氟乙烯)弯嘴洗瓶

PFA材质&#xff0c;又称可溶性聚四氟乙烯&#xff0c;是进口的高纯原材料&#xff0c;耐强酸强碱耐腐蚀和各种有机溶剂。 常用规格:30ml/60ml/100ml/250ml/500ml 产品特性 1、耐高低温&#xff1a;使用温度可达-200~260℃&#xff1b; 2、可打刻度&#xff0c;高度透明&#x…

20240330-0402-湖南长沙之旅-橘子洲,五一广场,国金广场,湖南博物馆

0330 复试&#xff0c;无语中&#xff0c;面试中文部分居然也是拉了坨大的 0331 晚上 感觉忙完复试&#xff0c;有种偶然感&#xff0c;跟自己设想的又不一样&#xff0c;感觉方向感真的差&#xff0c;压中得没多少。 刚忙完考试&#xff0c;去五一附近住&#xff0c;还是一…

wpf 自定义命令

自定义命令 MyCommand.cs public class MyCommand : ICommand {private readonly Action<Object> execAction;private readonly Func<Object,bool> changedFunc;public event EventHandler? CanExecuteChanged;public MyCommand(Action<object> execAction…

微信开发工具——进行网页授权

微信开发工具——进行网页授权 微信公众平台设置 1.在首页创建好自己的订阅号 网站&#xff1a;https://mp.weixin.qq.com/ 点击立即注册,在选择订阅号&#xff08;个人创建使用&#xff09; 之后按流程填写后&#xff0c;点击设置与开发-------->基本配置&#xff0c;这…

C++ //练习 11.4 扩展你的程序,忽略大小写和标点。例如,“example.“、“exmaple,“和”Example“应该递增相同的计数器。

C Primer&#xff08;第5版&#xff09; 练习 11.4 练习 11.4 扩展你的程序&#xff0c;忽略大小写和标点。例如&#xff0c;“example.”、"exmaple,"和”Example"应该递增相同的计数器。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工…

泰迪智能科技携手韶关学院共建实训基地

3月28日&#xff0c;韶关学院数学与统计学院院长宋杰、数学与统计学院副院长李少勇、数学与统计学院骨干教师邓四清、邝神芬、付林林莅临广东泰迪智能科技股份有限公司产教融合实训基地开展“韶关学院实习基地”揭牌仪式。泰迪智能科技高校事业部负责人施兴、培训业务部孙学镂、…

parallel linux虚拟机没有root权限

前言 今天刚在parallel上装上linux虚拟机&#xff0c;安装的是Debian发行版。用终端输入命令时&#xff0c;无意间发现当前用户竟然不是root用户&#xff0c;岂有此理&#xff01;众所周知&#xff0c;Linux系统一般安装之后都是默认root用户的&#xff0c;但是可能parallel先…

《系统架构设计师教程(第2版)》第8章-系统质量属性与架构评估-02-系统架构评估

文章目录 1. 一些重要概念1.1 敏感点 (Sensitivity Point)1.2 权衡点 (Tradeoff Point)1.3 风险承担者 (Stakeholders)1.3.1 系统生产者1.3.2 系统消费者1.3.3 系统服务人员1.3.4 其它人员 1.4 场景 (scenarios) 2. 系统架构评估方法2.1 基于场景的架构分析方法&#xff08;SAA…

【算法刷题day10】Leetcode:232.用栈实现队列、225. 用队列实现栈

文章目录 Leetcode 232.用栈实现队列解题思路代码总结 Leetcode 225. 用队列实现栈解题思路代码总结 stack、queue和deque对比 草稿图网站 java的Deque Leetcode 232.用栈实现队列 题目&#xff1a;232.用栈实现队列 解析&#xff1a;代码随想录解析 解题思路 一个栈负责进&a…

《编程菜鸟学 Python 数据分析》让工作自动化起来!

随着我国企业数字化和信息化的深入&#xff0c;企业对办公自动化的效率和灵活性要求越来越高。Python作为一种开源的软件应用开发方式&#xff0c;通过提供强大丰富的库文件包&#xff0c;极大地简化了应用开发过程&#xff0c;降低了技术门槛。Python开发有哪些优势、挑战以及…