电子政务和网站建设工作的总结,鹤壁市建设工程交易中心网站,医疗网站建设新闻,html素材Qt多文件传输功能实现前言代码实现概述客户端代码实现服务端代码效果展示结论前言
本次设计主要是为了功能上的实现#xff0c;因此对于ui界面的设计都是怎么简单怎么来的#xff0c;主要的功能就是实现多个文件的发送与接收#xff0c;即客户端发送#xff0c;服务端接收…
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 QTcpSocketclass TcpClient : public QMainWindow
{Q_OBJECTpublic:TcpClient(QWidget *parent 0);~TcpClient();void sendData();private:Ui::TcpClientClass ui;int port;QString ip;QTcpSocket *tcpSocket; //服务端连接套接字QFile locFile; //待发送的文件QListQString fileNames;QListQString paths;QListqint64 fileSizes;qint64 sendSize;int sendTime;private slots:void slotSend(); //发送void slotOpen(); //打开文件void sendMessage(); //传输文件void sendData(int);
};#endif // TCPCLIENT_Htcpclient.cpp文件
#include tcpclient.h
#include QFileDialog
#include QtDebug
#include QFileInfoTcpClient::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:headendlhead.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解决粘包问题结构数据封包拆包