一.前言
楼主在前面的文章中Qt笔记(六十九)之QWebSocket传输文件
简单介绍了如何传输文件,但是没有提示传输文件的进度,从用户角度来说,体验不好,于是就需要增加一个进度条,给用户直观的提示
二.实现的过程
1.思路描述:进度条提示进度,就表明是需要分块传输的,每完成一块就更新进度条,知道进度100%
分块传输,就会遇到一个问题,什么传输开始,又什么时候传输结束,于是就需要两个标志,传输开始的标志与传输结束的标志
理顺了以上的问题,思路也就出来了:将文件分块,每次传输特定字节的块,在传输之前,先发送一个标志,告诉服务器即将开始传输文件,然后开始传输,传输结完成之后,再发一个结束标志告知服务器,服务器可以将接收到二进制流保存为特定的文件
2.核心代码实现
2.1客户端
void ClientWidget::on_pushButton_4_clicked()
{
qDebug()<<"选择文件,并发送";
QString sendFile = QFileDialog::getOpenFileName(this,QStringLiteral("选择发送文件"),"C://","TEXT(*.txt)");
if(sendFile.isEmpty())
return;
// 先发送文件名,可以先裁剪剩下文件名,楼主为了方便,直接发送文件路径
webSocket.sendTextMessage("send_file_name:"+sendFile);
// 开始读取文件内容
QFile file(sendFile);
if(!file.open(QIODevice::ReadOnly))
return;
// 发送文件传输开始标志
webSocket.sendTextMessage("send_start");
// 读取文件
QByteArray data = file.readAll();
// 设置进度条属性
int MAX_BYTE=20; // 定义一次传输最大字节
ui->progressBar->setMinimum(0);
ui->progressBar->setMaximum(data.length()%MAX_BYTE==0?data.length()/MAX_BYTE:data.length()/MAX_BYTE+1);
ui->progressBar->setValue(0);
int idx=0;
for(int i=0;i<data.length();i+=MAX_BYTE)
{
webSocket.sendBinaryMessage(data.mid(i,MAX_BYTE));
idx++;
// 更新进度条
ui->progressBar->setValue(idx);
mySleep(500); // y延迟500ms 凸显进度条效果
}
// webSocket.sendBinaryMessage(data);
file.close();
// 发送文件传输结束标志
webSocket.sendTextMessage("send_end");
}
2.2服务端
void ServerWidget::onTextMessageReived(QString msg)
{
ui->textEdit_2->append(QDateTime::currentDateTime().toString()+":客户端发来消息:"+msg);
QString flag="send_file_name";
if(msg.contains(flag))
{
qDebug()<<"客户端上传的文件名:"+msg.mid(flag.length()+1);
}
if(msg=="send_start")
{
qDebug()<<"开始上传";
uploadData.clear();
}
if(msg=="send_end")
{
qDebug()<<"上传结束,开始保存";
QString saveName = QDateTime::currentDateTime().toString("yyyy-MM-dd HH-mm-ss")+".txt";
QFile file(saveName);
if(file.open(QIODevice::WriteOnly))
{
file.write(uploadData);
file.close();
qDebug()<<"服务器保存好上传的文件";
}
// 保存完清除
uploadData.clear();
}
}
void ServerWidget::onBinaryReived(const QByteArray ba)
{
qDebug()<<"onBinaryReived:"<<ba.toHex();
// 追加二进制流
uploadData.append(ba);
}
三.演示效果