Qt多文件传输功能实现及方法概述

Qt多文件传输功能实现

    • 前言
    • 代码实现概述
      • 客户端代码实现
      • 服务端代码
      • 效果展示
    • 结论

前言

本次设计主要是为了功能上的实现,因此对于ui界面的设计都是怎么简单怎么来的,主要的功能就是实现多个文件的发送与接收,即客户端发送,服务端接收保存,并且删去客户端的已发送的文件。

代码实现概述

这里就不在概述tcp通信的相关的内容,主要围绕本文设计进行叙述:
第一就是文件发送的流程图,单次文件内容发送主要分为两次,首先是文件名,可用于服务端建立新的文件;其次是文件大小,可用服务端判断是否完全接收完;最后是文件地址,用于服务端删除客户端发送的文件,也可以把这认为是简单的协议:
在这里插入图片描述
第二就是多文件的发送:这里用到了QFileDialog类的getOpenFileNames函数(可以固定打开文件的类型),返回QStringList的文件路径集合,接下来就是遍历发送。
第三就是防止发生粘包的情况,使用QIODevice类waitForBytesWritten函数,每次等待数据内容发送。

客户端代码实现

tcpclient.h文件:

#ifndef TCPCLIENT_H
#define TCPCLIENT_H#include <QtWidgets/QMainWindow>
#include "ui_tcpclient.h"
#include <QHostAddress>
#include <QFile>
#include <QTcpSocket>class TcpClient : public QMainWindow
{Q_OBJECTpublic:TcpClient(QWidget *parent = 0);~TcpClient();void sendData();private:Ui::TcpClientClass ui;int port;QString ip;QTcpSocket *tcpSocket;   //服务端连接套接字QFile locFile;      //待发送的文件QList<QString> fileNames;QList<QString> paths;QList<qint64> fileSizes;qint64 sendSize;int sendTime;private slots:void slotSend();   //发送void slotOpen();   //打开文件void sendMessage();  //传输文件void sendData(int);
};#endif // TCPCLIENT_H

tcpclient.cpp文件:

#include "tcpclient.h"
#include <QFileDialog>
#include <QtDebug>
#include <QFileInfo>TcpClient::TcpClient(QWidget *parent): QMainWindow(parent)
{ui.setupUi(this);//初始化port = 8081;ip = "127.0.0.1";connect(ui.openButton,SIGNAL(clicked()),this,SLOT(slotOpen()));connect(ui.sendButton,SIGNAL(clicked()),this,SLOT(slotSend()));connect(ui.closeButton,SIGNAL(clicked()),this,SLOT(close()));ui.openButton->setEnabled(true);ui.sendButton->setEnabled(false);
}TcpClient::~TcpClient()
{}void TcpClient::slotOpen()
{//初始化数据fileNames.clear();fileSizes.clear();sendTime = 0;paths = QFileDialog::getOpenFileNames(this,"open file");    //当前目录下if (!paths.isEmpty()){for (int i = 0; i < paths.size(); i++){locFile.setFileName(paths[i]);if (locFile.open(QIODevice::ReadOnly)){//获取发送文件的信息QFileInfo info(paths[i]);fileNames.append(info.fileName());  //文件名fileSizes.append(info.size());      //文件大小}qDebug()<<"fileName:"<<fileNames[i]<<"fileSize:"<<fileSizes[i]<<"path:"<<paths[i];}}ui.sendButton->setEnabled(true);
}void TcpClient::slotSend()
{//创建连接服务器tcpSocket = new QTcpSocket(this);tcpSocket->connectToHost(ip,port);  //连接服务器,并发出connected()信号connect(tcpSocket,SIGNAL(connected()),this,SLOT(sendMessage()));   //传输文件槽函数
}void TcpClient::sendMessage()
{qDebug()<<"link successful";ui.sendButton->setEnabled(false);//先发送头,自定义组包, 文件名#文件大小,不是文件数据locFile.setFileName(paths[sendTime]);locFile.open(QIODevice::ReadOnly);QString head = QString("head#%1#%2#%3").arg(fileNames[sendTime]).arg(fileSizes[sendTime]).arg(paths[sendTime]);qDebug()<<"head:"<<head<<endl<<head.size();//发送头qint64 len = tcpSocket->write(head.toUtf8().data());tcpSocket->waitForBytesWritten();  //等待数据内容发送if (len > 0){sendData(sendTime); //发送内容数据}
}void TcpClient::sendData(int i)
{QByteArray buf = locFile.readAll();qint64 len = tcpSocket->write(buf);tcpSocket->waitForBytesWritten();  //等待数据内容发送sendSize = len;qDebug()<<"sendSize:"<<sendSize;if (sendSize == fileSizes[i]){qDebug()<<"send successful";locFile.close();tcpSocket->close();}if (i < paths.size()-1){slotSend();sendTime++;}
}

服务端代码

因为服务端的代码也比较简单,这里就不展示了。

效果展示

因为只是简单的功能设计,因此没有直观的展示,主要是客户端的发送截图,以及服务端对接收二进制文件内容的打印。
客户端界面:
在这里插入图片描述
服务端控制台打印文件内容:
在这里插入图片描述

结论

本次设计对单次文件传输是没什么问题的,主要的多文件传输时的粘包现象,本次设计经过验证对于多个小文件传输是没问题的,但是不排除大量的大文件不会出现问题。因此就需要一个更好更稳定的协议来保证,这次只是简单使用了等待传输的函数,后面我也会进一步进行更好的封包与解包的通信操作。见TCP解决粘包问题(结构数据封包拆包)

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

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

相关文章

从java到C++入门

C基础知识前言基础前言 当初为了赶一波互联网热潮自学了java&#xff0c;如今因为需要就从java转向C开发&#xff0c;于是就有了java到C入门&#xff0c;每次的学习我都会记录一下C的学习历程。 基础 C对于内存的控制管理比java要有更多要求&#xff0c;因此C对于变量的创建…

C++灵魂->指针

C灵魂->指针地址指针野指针空指针 【内存动态分配】指针变量的运算&#xff08;&#xff0c;-&#xff0c;&#xff0c;--&#xff09;指针与一维数组地址 计算机将内存以单个字节为单位分开&#xff0c;并对每个字节进行唯一性编号&#xff0c;那么这个编号就是地址。 取…

TCP解决粘包问题(结构数据封包拆包)

TCP封包拆包前言封包一、包结构二、封包方法拆包总结前言 TCP协议(Transmission Control Protocol&#xff09;是一种面向连接的、可靠的、基于字节流的通信协议&#xff0c;即TCP采用字节流的方式&#xff0c;以字节为单位传输字节序列。 如果简单的发送长串的数据流&#xf…

拆包--缓冲区查找包头及包尾偏移

缓冲区查找包头及包尾偏移前言一、采用动态数组QByteArray的自带函数二、采用字节对比方法测试代码前言 根据前面所讲的内容封包拆包&#xff0c;当将网络中的数据读出存储在自定义缓冲区QByteArray中&#xff0c;则对数据包进行拆分。则首先要进行的工作就是找到包头的位置及…

5自适应单页源码_超详细!如何建立一个CPA单页网站,附高转化CPA模板源码

做CPA的老手一般都会建立一个CPA单页站&#xff0c;用来提升转化&#xff0c;提高推广质量。今天教大家搭建一个完整的CPA单页站搭建一个网站需要3样东西&#xff1a;域名服务器网站源码一、购买域名域名就是你网站的地址&#xff0c;建议从万网购买就可以&#xff0c;比较方便…

20154319 《网络对抗技术》后门原理与实践

一、实验说明 任务一&#xff1a;使用netcat获取主机操作Shell&#xff0c;cron启动 (0.5分) 任务二&#xff1a;使用socat获取主机操作Shell, 任务计划启动 (0.5分) 任务三&#xff1a;使用MSF meterpreter&#xff08;或其他软件&#xff09;生成可执行文件&#xff0c;利用…

强制类型转换的取整及四舍五入取整

强制类型转换取整相关前言取整方法例&#xff1a;(signed int)double四舍五入取整前言 开发中一般运算过程都采用浮点类型数据以免出现运算不精确的错误&#xff0c;而当运算结果需要时整型的时候就需要对浮点类型的结果进行取整处理&#xff0c;而取整的方法有向上取整&#…

关于字节对齐

关于字节对齐前言意义自定义字节对齐存储空间内存读取效率平台适应性结论前言 计算机中的内存空间大小是以字节&#xff08;byte&#xff09;为基本单位划分的&#xff0c;从理论上讲似乎对任何类型的变量的访问可以从任何地址开始&#xff0c;而计算机并非逐字节大小读写内存…

c++中的多线程

使用 std::thread 时需要包含 #include<thread> 头文件&#xff0c;定义了表示线程的类、用于互斥访问的类与方法等。 参考网址&#xff1a; https://blog.csdn.net/liuker888/article/details/46848905https://blog.csdn.net/fengbingchun/article/details/73393229成员…

C++ reverse memcpy

C reverse memcpy前言基于QT的测试样例结果前言 C 实现翻转memcpy 基于QT的测试样例 代码如下&#xff1a; #include <iostream> #include <QtCore/QCoreApplication> #include <QDebug>using namespace std;void *reversememcpy(void *out, const void *…

打架程序_学生打架不知道怎么处理?一般程序了解下,对你或许有帮助

很多新老师&#xff0c;对处理学生问题的步骤其实还不是很了解&#xff0c;一遇到学生问题就很苦恼&#xff0c;用的方法很多&#xff1a;或劝、或骂、或赏、或罚&#xff0c;但总是觉得不得要领。今天我想通过昨天我处理的一个实例&#xff0c;针对性的聊一聊这个问题。希望对…

jsp中设置自动换行_办公技巧—Word中如何设置自动生成序号

我们经常会用到Word来编辑文档&#xff0c;经常需要在文档中插入各种序号。如果一个个手动输入这些序列号&#xff0c;会降低我们的工作效率。那么&#xff0c;这种情况下&#xff0c;我们该怎么办呢&#xff1f;今天&#xff0c;小编就教各位Word中设置自动生成序号的小技巧&a…

mongodb如何根据字段(数组类型)的长度排序_大数据存储技术选型(七)——MongoDB设计模式及索引优化...

关系数据库的时代关系数据库的设计理念假设你有一台车&#xff0c;你需要给它存起来&#xff0c;给它找个停车位。传统数据库的存储方式就相当于&#xff0c;把这个车的所有零件拆下来&#xff0c;放在存放对应零件的盒子里&#xff0c;需要用的时候&#xff0c;再把他们取出来…

幼小衔接语言教案上c册_关于幼小衔接,这里有你最想要的解答

相信很多家长都会发现&#xff0c;在孩子即将步入小学的前一年或者半年左右&#xff0c;身边同龄的孩子有一部分会放弃大班的学习&#xff0c;转而去幼小衔接班了。就算平时再佛系的妈妈&#xff0c;内心也会焦虑&#xff0c;产生疑问&#xff1a;到底要不要上幼小衔接班&#…

每日一题20180330-Linux

一、问题 1.1 统计/var/log/下所有文件个数 1.2 查找出/var/log目录下面修改时间是7天以前&#xff0c;大小在50k到2M之间&#xff0c;并以.log结尾的文件把这些文件复制到/data目录中 1.3 设置一条Iptables规则&#xff0c;允许192.168.10.0段访问873端口&#xff1f; 二、答案…

前台文件_欧木瑾怎么定制办公前台?

前台是一个反映公司整体形象的地方。这是给客户和商业伙伴留下印象的第一个地方。因此&#xff0c;芜湖绿木家具有限公司欧木瑾小编说公司的前台装修不能马虎。前台的设计风格与材料的使用有很大关系。从细节上看&#xff0c;这是材料的精美运用。这里是如何设计一个好的前台。…

单纯形法只有两个约束条件_10分钟掌握对偶单纯形法

只听名字的话会感觉对偶单纯形法和对偶问题关系很大&#xff0c;其实不然(想要了解对偶问题的话可以看我之前的文章)。对偶单纯形法在我看来和大M法以及两阶段法很像&#xff0c;都是用来补充纯粹的单纯形法无法解决特殊问题的缺陷。而且对偶单纯形法更加“强大”&#xff0c;因…

linix防火墙设置之顺序设置问题 -- 解决防火墙规则顺序和插入规则到指定序号的问题...

转载于百度经验&#xff1a;https://jingyan.baidu.com/article/ae97a646ce58c2bbfd461d90.html 无论是硬件防火墙还是软件防火墙都会有一个规则序列的问题&#xff0c;规则顺序会影响到规则的生效情况&#xff0c;所以这个必须得注意&#xff0c;下面小编与大家分享一下如何注…

Ubuntu安装完后设置root密码

安装完Ubuntu 14.04后默认是没有主动设置root密码的&#xff0c;也就无法进入根用户。 相关阅读&#xff1a; Ubuntu 14.04 下载、安装、配置 整理汇总 页面 http://www.linuxidc.com/Linux/2014-04/100370.htm Windows 7下硬盘安装Ubuntu 14.04永久更新地址&#xff1a; http:…

js 中转换成list集合_程序员:java集合介绍-List,具说很详细,你不来看看?

Java集合介绍作为一个程序猿&#xff0c;Java集合类可以说是我们在工作中运用最多、最频繁的类。相比于数组(Array)来说&#xff0c;集合类的长度可变&#xff0c;更加方便开发。Java集合就像一个容器&#xff0c;可以存储任何类型的数据&#xff0c;也可以结合泛型来存储具体的…