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 93
    int 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协议(三)

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

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

相关文章

比特币和区块链详解: Bitcoin: A Peer-to-Peer Electronic Cash System白皮书

背景 考虑当前手机上的余额、手里的现金&#xff0c;其实本质都归属于银行发给我们的欠条&#xff0c;是在政府监管下的流通货币。当我们在做交易时&#xff0c;银行属于可信第三方&#xff0c;银行发行的货币在交易过程中起到了重要作用。但基于金融机构的受信任第三方容易受…

使用pytorch构建带梯度惩罚的Wasserstein GAN(WGAN-GP)网络模型

本文为此系列的第三篇WGAN-GP&#xff0c;上一篇为DCGAN。文中仍然不会过多详细的讲解之前写过的&#xff0c;只会写WGAN-GP相对于之前版本的改进点&#xff0c;若有不懂的可以重点看第一篇比较详细。 原理 具有梯度惩罚的 Wasserstein GAN (WGAN-GP)可以解决 GAN 的一些稳定性…

【WEEK6】 【DAY2】DQL查询数据-第二部分【中文版】

2024.4.2 Tuesday 接上文【WEEK6】 【DAY1】DQL查询数据-第一部分【中文版】 目录 4.4.连接查询4.4.1.JOIN 对比4.4.2.七种JOIN4.4.3.例4.4.3.1.本例中INNER JOIN和RIGHT JOIN结果相同4.4.3.2.LEFT JOIN4.4.3.3.查询缺考的同学4.4.3.4.思考题&#xff1a;查询参加了考试的同学信…

Visual Studio安装下载进度为零已解决

因为在安装pytorch3d0.3.0时遇到问题&#xff0c;提示没有cl.exe&#xff0c;VS的C编译组件&#xff0c;可以添加组件也可以重装VS。查了下2019版比2022问题少&#xff0c;选择了安装2019版&#xff0c;下面是下载安装时遇到的问题记录&#xff0c;关于下载进度为零网上有三类解…

redis的哈希Hash

哈希是一个字符类型的字段和值的映射表&#xff0c;简单来说就是一个键值对的集合。 查看里面的name或者age在不在里面&#xff0c;0说明已经删了的 用来获取person里的键

[C#]使用OpencvSharp去除面积较小的连通域

【C介绍】 关于opencv实现有比较好的算法&#xff0c;可以参考这个博客OpenCV去除面积较小的连通域_c#opencv 筛选小面积区域-CSDN博客 但是没有对应opencvsharp实现同类算法&#xff0c;为了照顾懂C#编程同学们&#xff0c;因此将 去除面积较小的连通域算法转成C#代码。 方…

Java获取IP地址以及MAC地址(附Demo)

目录 前言1. IP及MAC2. 特定适配器 前言 需要获取客户端的IP地址以及MAC地址 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader;public class test {public static void main(String[] args) {try {// 执行命令Process process…

Nginx在Kubernetes集群中的进阶应用

简介 在现代DevOps环境中&#xff0c;Nginx作为负载均衡器与Kubernetes的Ingress资源的结合&#xff0c;为应用程序提供了强大的路由和安全解决方案。本文将深入探讨如何利用Nginx的灵活性和功能&#xff0c;实现高效、安全的外部访问控制&#xff0c;以及如何配置Ingress以优…

智能小车测速(3.26)

模块介绍&#xff1a; 接线&#xff1a; VCC -- 3.3V 不能接5V&#xff0c;否则遮挡一次会触发3次中断 OUT -- PB14 测速原理&#xff1a; cubeMX设置&#xff1a; PB14设置为gpio中断 打开定时器2&#xff0c;时钟来源设置为内部时钟&#xff0c;设置溢出时间1s&#xff0c…

上位机图像处理和嵌入式模块部署(qmacvisual图像清晰度)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 做过isp的同学都知道&#xff0c;图像处理里面有一个3a&#xff0c;即自动曝光、自动白平衡和自动对焦。其中自动对焦这个&#xff0c;就需要用输入…

qt通过setProperty设置样式表笔记

在一个pushbutton里面嵌套两个label即可&#xff0c;左侧放置图片label&#xff0c;右侧放置文字label&#xff0c;就如上图所示&#xff1b; 但是这时的hover&#xff0c;press的伪状态是没有办法“传递”给里面的控件的&#xff0c;对btn的伪状态样式表的设置&#xff0c;是不…

IP SSL的应用与安装

IP SSL&#xff0c;即互联网协议安全套接字层&#xff0c;它是一种为网络通信提供安全及数据完整性的安全协议。在网络传输过程中&#xff0c;IP SSL可以对数据进行加密&#xff0c;这样即便数据在传输途中被截取&#xff0c;没有相应的解密密钥也无法解读内容。这一过程如同将…

防抖节流面试

1、防抖 1.1、条件 1、高频 2、耗时&#xff08;比如console不算&#xff09; 3、以最后一次调用为准 刷到个神评论&#xff0c;回城是防抖&#xff0c;技能cd是节流 1.2、手写 传参版本 function debounce(fn,delay){let timerreturn function(...args){//返回函数必须是普…

动态规划详解(Dynamic Programming)

目录 引入什么是动态规划&#xff1f;动态规划的特点解题办法解题套路框架举例说明斐波那契数列题目描述解题思路方式一&#xff1a;暴力求解思考 方式二&#xff1a;带备忘录的递归解法方式三&#xff1a;动态规划 推荐练手题目 引入 动态规划问题&#xff08;Dynamic Progra…

QT子窗口关闭时自动释放及注意事项

先说方法&#xff0c;很简单&#xff0c;有如下API函数可用&#xff1a; testDialog->setAttribute( Qt::WA_DeleteOnClose, true )&#xff1b; 他的官方解释如下&#xff1a; 最后&#xff0c;说一个注意事项&#xff1a; 最近写python程序比较多&#xff0c;回过头来&a…

OPPO VPC 实践探索

01 概述 一年前(20年6月)&#xff0c;OPPO云网络技术底座开始支持VPC方案&#xff0c;解决了用户担心的云上安全和虚拟实例的性能问题。我们称这个版本为VPC1.0&#xff0c;其采用了先进的智能网卡加速和VXLAN隧道隔离技术&#xff0c;实现了VPC从无到有的突破。 然而由于业务快…

爬虫部署平台crawlab使用说明

Crawlab 是一个基于 Go 语言的分布式网络爬虫管理平台&#xff0c;它支持 Python、Node.js、Jar、EXE 等多种类型的爬虫。 Crawlab 提供了一个可视化的界面&#xff0c;并且可以通过简单的配置来管理和监控爬虫程序。 以下是 Crawlab 的一些主要优点&#xff1a; 集中管理&am…

绿联 安装Mysql数据库

绿联 安装Mysql数据库 1、镜像 mysql:5.7 数据库5.7.x系列。 mysql:8 数据库8.x.x系列&#xff0c;安装方式相同。 2、安装 2.1、拉取镜像 拉取5.7.x版本的镜像。 2.2、基础设置 重启策略&#xff1a;第三或第四项均可。 2.3、网络 桥接即可。 2.4、命令 在原有的“mys…

概率论基础——拉格朗日乘数法

概率论基础——拉格朗日乘数法 概率论是机器学习和优化领域的重要基础之一&#xff0c;而拉格朗日乘数法与KKT条件是解决优化问题中约束条件的重要工具。本文将简单介绍拉格朗日乘数法的基本概念、应用以及如何用Python实现算法。 1. 基本概念 拉格朗日乘数法是一种用来求解…

EPSON机器人仿真实战攻略:从设置通信到运行调试一网打尽!

EPSON机器人 仿真测试深度教程 机器人还没到,怎么提前验证写好得机器人程序? 强大的仿真功能来了!本文详细深入的介绍了仿真的功能,一步步教会你如何仿真! 请先关注公众号收藏,防止走丢! 需要先设置电脑与控制器通信的虚拟连接,设置-电脑与控制器通信-增加-选择连接…