Qt实现TFTP Server和 TFTP Client(三)

3.2 Client

Client包括下面3个类:

  • ClientSocke
  • TFtpClient
  • TFtpClientWidget
3.2.1 ClientSocke

ClientSocke从BaseUdp派生实现write接口.

3.2.1.1 ClientSocke定义
#include "baseudp.h"class QUdpSocket;
class ClientSocket : public BaseUdp
{
public:ClientSocket(QUdpSocket* socket): socket_(socket){}uint32_t write(const char* data, size_t size) override;
private:QUdpSocket* socket_;
};

成员函数说明:

  • write 重载函数,实现父类BaseUdp中定义的write接口。
3.2.1.2 ClientSocke实现
#include "clientsocket.h"
#include <QUdpSocket>uint32_t ClientSocket::write(const char* data, size_t size)
{return socket_->write(data, size);
}

函数实现说明:

  • 直接调用QUdpSocket对象的write接口。
3.2.2 TFtpClient

TFtpClient类通过TFtpClientFile类实现一个TFTP客户端,实现上下载文件。

3.2.2.1 TFtpClient定义
class QUdpSocket;
class TFtpClient : public QObject
{Q_OBJECT
public:explicit TFtpClient(QObject *parent = nullptr);void setHostPort(QString const& host, quint16 port);void getFile(QString const& localFileName, QString const& remoteFileName);void putFile(QString const& localFileName, QString const& remoteFileName);bool isPut() const { return isPut_; }
public slots:void stopFileTransfer();
signals:void started();void progress(quint64 bytes, quint64 total);void error(QString const& text);void finished();
private slots:void connected();void connectError(QAbstractSocket::SocketError error);void readPendingDatagrams();
private:QUdpSocket* socket;QString host_;quint16 port_;QString localFileName_;QString remoteFileName_;TFtpClientFile::Ptr tftpFile_;bool isPut_ = false;
};

成员函数说明:

  • setHostPort 配置TFTP服务器的IP地址和端口.
  • getFile 从TFTP服务器下载文件.
  • putFile 向TFTP服务器上传文件.
  • isPut 是否是上传
  • stopFileTransfer 终止文件传输

信号说明:

  • started 文件传输开始信号
  • progress 传输进度信号
  • error 错误信号
  • finished 传输完成信号

槽函数说明:

  • connected 与TFTP服用器连接成功后的处理函数
  • connectError 与TFTP服用器连接失败后的处理函数
  • readPendingDatagrams 从TFTP服用器读数处理函数
3.2.2.2 TFtpClient实现
  • 构造函数
TFtpClient::TFtpClient(QObject *parent): QObject(parent), socket(new QUdpSocket(this))
{connect(socket, &QUdpSocket::readyRead,this, &TFtpClient::readPendingDatagrams);connect(socket, &QUdpSocket::connected,this, &TFtpClient::connected);connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(connectError(QAbstractSocket::SocketError)));
}

函数说明:

  • 创建QUdpSocket对象socket

  • 连接socket的信号和对应槽函数。

  • setHostPort/getFile/putFile

void TFtpClient::setHostPort(QString const& host, quint16 port)
{host_ = host;port_ = port;
}void TFtpClient::getFile(QString const& localFileName, QString const& remoteFileName)
{isPut_ = false;localFileName_ = localFileName;remoteFileName_ = remoteFileName;socket->connectToHost(host_, port_);
}void TFtpClient::putFile(QString const& localFileName, QString const& remoteFileName)
{isPut_ = true;localFileName_ = localFileName;remoteFileName_ = remoteFileName;socket->connectToHost(host_, port_);
}

函数说明:

  • setHostPort 保存主机地址和端接口

  • getFile 保存本地文件名和远程文件名,设置为下载,连接TFTP服务器

  • putFile 保存本地文件名和远程文件名,设置为上传,连接TFTP服务器

  • stopFileTransfer/connected/connectError/readPendingDatagrams

void TFtpClient::stopFileTransfer()
{socket->disconnectFromHost();
}void TFtpClient::connected()
{ClientSocket* udp = new ClientSocket(socket);tftpFile_ = TFtpClientFile::Ptr(new TFtpClientFile(udp));bool isOK = true;if(isPut_)isOK = tftpFile_->putFile(localFileName_.toStdString(),remoteFileName_.toStdString(), TFtp::BINARY);elseisOK = tftpFile_->getFile(localFileName_.toStdString(),remoteFileName_.toStdString(), TFtp::BINARY);if(!isOK)emit error("Local File not Found");elseemit started();
}void TFtpClient::connectError(QAbstractSocket::SocketError)
{emit error("Connect host is failed");
}void TFtpClient::readPendingDatagrams()
{while (socket->hasPendingDatagrams()) {QNetworkDatagram datagram = socket->receiveDatagram();QByteArray d = datagram.data();if(tftpFile_){tftpFile_->process((uint8_t *)d.data(), d.size());emit progress(tftpFile_->file_bytes(), tftpFile_->filesize());if(tftpFile_->is_finished()){if(tftpFile_->is_error())emit error(QString::fromStdString(tftpFile_->error_msg()));elseemit finished();}}}
}

函数说明:

  • stopFileTransfer 与TFTP服务器断开连接,终止文件传输。
  • connected 连接上TFTP服务器后,创建TFtpClientFile对象,开始上传/下载文件
  • connectError 与TFTP服务器连接失败,发送连接失败信号量。
  • readPendingDatagrams 从TFTP服务器读取数据给TFtpClientFile对象处理,如果传输结束,有错误发送error信号,没错误发送finished信号。
3.2.3 TFtpClientWidget

TFtpClientWidget从QWidget派生一个窗口类,负责发起上下载文件,并显示文件传输进度等界面操作。

3.2.3.1 TFtpClientWidget定义
class TFtpClient;
class TFtpClientWidget : public QWidget
{Q_OBJECTpublic:TFtpClientWidget(QWidget *parent = nullptr);~TFtpClientWidget();private slots:void onGetFile();void onPutFile();void onStarted();void onProgress(quint64 bytes, quint64 total);void onStop();void onFinished();void onError(QString const& error);void onSelectLocalFile();
private:void enableButtons(bool enable);
private:Ui::TFtpClientWidget *ui;TFtpClient* tftpClient;
};
3.2.3.2 TFtpClientWidget实现
TFtpClientWidget::TFtpClientWidget(QWidget *parent): QWidget(parent), ui(new Ui::TFtpClientWidget), tftpClient(new TFtpClient(this))
{ui->setupUi(this);connect(ui->btnBrowse, SIGNAL(clicked()), this, SLOT(onSelectLocalFile()));connect(ui->btnGet, SIGNAL(clicked()), this, SLOT(onGetFile()));connect(ui->btnPut, SIGNAL(clicked()), this, SLOT(onPutFile()));connect(ui->btnBreak, SIGNAL(clicked()), this, SLOT(onStop()));connect(tftpClient, &TFtpClient::started, this, &TFtpClientWidget::onStarted);connect(tftpClient, &TFtpClient::progress, this, &TFtpClientWidget::onProgress);connect(tftpClient, &TFtpClient::finished, this, &TFtpClientWidget::onFinished);connect(tftpClient, &TFtpClient::error, this, &TFtpClientWidget::onError);
}TFtpClientWidget::~TFtpClientWidget()
{delete ui;
}void TFtpClientWidget::onGetFile()
{tftpClient->stopFileTransfer();tftpClient->setHostPort(ui->lineEditHost->text(), ui->spinBoxPort->value());tftpClient->getFile(ui->lineEditLocalFile->text(), ui->lineEditRemoteFile->text());ui->progressBar->setValue(0);
}void TFtpClientWidget::onPutFile()
{tftpClient->stopFileTransfer();tftpClient->setHostPort(ui->lineEditHost->text(), ui->spinBoxPort->value());tftpClient->putFile(ui->lineEditLocalFile->text(), ui->lineEditRemoteFile->text());ui->progressBar->setValue(0);
}void TFtpClientWidget::onStarted()
{enableButtons(false);
}void TFtpClientWidget::onProgress(quint64 bytes, quint64 total)
{if(total > 0)ui->progressBar->setValue(bytes * 100 / total);else{int value = ui->progressBar->value();ui->progressBar->setValue(QRandomGenerator(value).bounded(value, 99));}
}void TFtpClientWidget::onStop()
{enableButtons(true);tftpClient->stopFileTransfer();
}void TFtpClientWidget::onFinished()
{if(tftpClient->isPut())QMessageBox::information(this, "TFtpClient", "Put is done!");elseQMessageBox::information(this, "TFtpClient", "Get is done!");enableButtons(true);
}void TFtpClientWidget::onError(QString const& error)
{QMessageBox::critical(this, "TFtpClient", error);enableButtons(true);
}void TFtpClientWidget::onSelectLocalFile()
{static QString filePath;QFileDialog dialog(this, tr("Select File"), filePath, tr("All files (*.*)"));if(dialog.exec() == QDialog::Rejected)return;QStringList fileNames = dialog.selectedFiles();if(fileNames.isEmpty())return;QString fileName = fileNames.first();filePath = QFileInfo(fileName).filePath();ui->lineEditLocalFile->setText(fileName);
}void TFtpClientWidget::enableButtons(bool enable)
{ui->btnGet->setEnabled(enable);ui->btnPut->setEnabled(enable);ui->btnBreak->setDisabled(enable);
}

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

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

相关文章

【C++】每日一题 45 跳跃游戏

给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] 处&#xff0c;你可以跳转到任意 nums[i j] 处: 0 < j < nums[i] i j < n 返回到达 nums[n - 1] 的最…

SQLite中的原子提交(四)

返回&#xff1a;SQLite—系列文章目录 上一篇:SQLite数据库成为内存中数据库&#xff08;三&#xff09; 下一篇&#xff1a;SQLite使用的临时文件&#xff08;二&#xff09; 1. 引言 SQLite等事务数据库的一个重要特性 是“原子提交”。 原子提交意味着所有数据库都在…

深度学习十大算法之图神经网络(GNN)

一、图神经网络的基础 图的基本概念 图是数学中的一个基本概念&#xff0c;用于表示事物间复杂的关系。在图论中&#xff0c;图通常被定义为一组节点&#xff08;或称为顶点&#xff09;以及连接这些节点的边。每个边可以有方向&#xff0c;称为有向边&#xff0c;或者没有方向…

网络原理讲解

目标 网络发展史 独立模式 独立模式&#xff1a;计算机之间相互独立&#xff1b; 网络互连 随着时代的发展&#xff0c;越来越需要计算机之间互相通信&#xff0c;共享软件和数据&#xff0c;即以多个计算机协同工作来完成 业务&#xff0c;就有了网络互连。 网络互连&a…

学习笔记:MYSQL数据库基础知识

MYSQL数据库基础知识学习笔记 MYSQL基础学习数据库相关概念现主流数据库排名数据模型SQL分类SQL数据库基础操作 2024/3/27 学习资料&#xff1a;黑马程序员:MYSQL MYSQL基础学习 数据库和数据库管理系统(DBMS) 数据库: 是存储数据的集合&#xff0c;包括表、视图、索引等对象…

存内计算:释放潜能的黑科技

什么是存内计算&#xff1f; 存内计算技术是一种新型的计算架构&#xff0c;它将存储器和计算单元融合在一起&#xff0c;以实现高效的数据处理。存内计算技术的优势在于能够消除数据搬运的延迟和功耗&#xff0c;从而提高计算效率和能效比。目前&#xff0c;存内计算技术正处…

React Native获取及监听网络状态

在React Native中&#xff0c;要获取和监听网络状态&#xff0c;你可以使用react-native-netinfo库&#xff08;以前是核心库的一部分&#xff0c;但在React Native 0.60之后被移出并作为一个独立的库提供&#xff09;。以下是使用这个库来获取和监听网络状态的基本步骤&#x…

苹果Find My产品需求增长迅速,伦茨科技ST17H6x芯片供货充足

苹果的Find My功能使得用户可以轻松查找iPhone、Mac、AirPods以及Apple Watch等设备。如今Find My还进入了耳机、充电宝、箱包、电动车、保温杯等多个行业。苹果发布AirTag发布以来&#xff0c;大家都更加注重物品的防丢&#xff0c;苹果的 Find My 就可以查找 iPhone、Mac、Ai…

jupyter notebook导出含中文的pdf(LaTex安装和Pandoc、MiKTex安装)

用jupyter notebook导出pdf时&#xff0c;因为报错信息&#xff0c;需要用到Tex nbconvert failed: xelatex not found on PATH, if you have not installed xelatex you may need to do so. Find further instructions at https://nbconvert.readthedocs.io/en/latest/install…

pytorch中的torch.hub.load()

pytorch提供了torch.hub.load()函数加载模型&#xff0c;该方法可以从网上直接下载模型或是从本地加载模型。官方文档 torch.hub.load(repo_or_dir, model, *args, sourcegithub, trust_repoNone, force_reloadFalse, verboseTrue, skip_validationFalse, **kwargs)参数说明&a…

Focal Modulation Networks聚焦调制网络

摘要 我们提出了 焦点调制网络 &#xff08;简称 FocalNets) &#xff0c;其中 自注意&#xff08; SA &#xff09;被 Focal Modulation 替换&#xff0c;这种机制 包括三个组件&#xff1a;&#xff08; 1 &#xff09;通过 depth-wise Conv 提取分级的上下文信息&#xff0…

吴恩达深度学习笔记:浅层神经网络(Shallow neural networks)3.6-3.8

目录 第一门课&#xff1a;神经网络和深度学习 (Neural Networks and Deep Learning)第三周&#xff1a;浅层神经网络(Shallow neural networks)3.6 激活函数&#xff08;Activation functions&#xff09;3.7 为什么需要非线性激活函数&#xff1f;&#xff08;why need a non…

Spring Cloud 九:服务间通信与消息队列

Spring Cloud 一&#xff1a;Spring Cloud 简介 Spring Cloud 二&#xff1a;核心组件解析 Spring Cloud 三&#xff1a;API网关深入探索与实战应用 Spring Cloud 四&#xff1a;微服务治理与安全 Spring Cloud 五&#xff1a;Spring Cloud与持续集成/持续部署&#xff08;CI/C…

react native hooks 页面出现重绘问题,如何解决

在React Native应用中&#xff0c;使用Hooks导致页面出现频繁重绘或性能问题时&#xff0c;可以尝试以下策略来优化和解决问题&#xff1a; 减少不必要的状态更新&#xff1a; 使用 React.memo 高阶组件包裹那些不需要每次父组件状态改变时都重新渲染的子组件。它通过浅比较pro…

Java Web-Maven

Maven是apache旗下的一个开源项目&#xff0c;是一款用于管理和构建java项目的工具 Maven的作用 1.依赖管理:方便快捷的管理项目依赖资源(jar包)&#xff0c;避免版本冲突问题 我们有的项目需要大量的jar包&#xff0c;采用手动导包的方式非常繁琐&#xff0c;并且版本升级也…

面试官:2PC和3PC有什么区别?

本文内容已收录至我的面试网站&#xff1a;www.javacn.site 在分布式事务中&#xff0c;通常使用两阶段协议或三阶段协议来保障分布式事务的正常运行&#xff0c;它也是 X/Open 公司定义的一套分布式事务标准。 X/Open 公司是由多家国际计算机厂商所组成的联盟组织&#xff0c;…

【前端】-【性能优化常识】

目录 前端性能优化指标首屏速度、白屏时间性能优化收效很大的操作&#xff1a;减少首屏资源体积收效不大或者特殊情况的优化操作 操作速度、渲染速度造成操作卡顿和渲染慢的场景性能优化 数据缓存 补充知识异步加载加载方式一&#xff1a;prefetch加载加载方式二&#xff1a;sc…

小迪安全48WEB 攻防-通用漏洞Py 反序列化链构造自动审计 bandit魔术方法

#知识点&#xff1a; 1、Python-反序列化函数使用 2、Python-反序列化魔术方法 3、Python-反序列化 POP 链构造&#xff08;payload构造&#xff09; 4、Python-自动化审计 bandit 使用 #前置知识&#xff1a; 函数使用&#xff1a; pickle.dump(obj, file) : 将对…

如何利用nginx在Centos上搭建文件服务器

第一步&#xff1a;创建export文件夹 其下soft文件夹和server文件夹 soft放软件压缩包&#xff0c;server放解压安装后的软件 第二步&#xff1a;yum -y install make gcc-c zlib zlib-devel libtool openssl openssl-devel libpcre3 libpcre3-dev 下载gcc 依赖环境安装 …

基于SIR模型的疫情发展趋势预测算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于SIR模型的疫情发展趋势预测算法.对病例增长进行SIR模型拟合分析&#xff0c;并采用模型参数拟合结果对疫情防控力度进行比较。整体思路为采用SIR微分方程模型…