我用TCP发送文件,但是发送的时候界面就会卡死,求解决!
代码如下,这是书上的一个TCP发送文件的例子,但是没有解决界面卡死不动的问题。
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
loadSize = 4*1024;
totalBytes = 0;
bytesWrinten = 0;
bytesToWrite = 0;
tcpClient = new QTcpSocket(this);
connect(tcpClient,SIGNAL(connected()),this,SLOT(startTransfer()) );
//当连接成功时发送connected()信号,我们开始传文件
connect(tcpClient,SIGNAL(bytesWritten(qint64)),this,SLOT(updataClientProgress(qint64)) );
//当有数据发送时,就更新进度条
connect(tcpClient,SIGNAL(error(QAbstractSocket::SocketError)),this
,SLOT(displayError(QAbstractSocket::SocketError)) );
//当出错时,显示出错信息
ui->sendButton->setEnabled(false);
//开始使发送不可用
}
Widget::~Widget()
{
delete ui;
}
void Widget::openFile()
{
qDebug() << "openFile()" << endl;
fileName = QFileDialog::getOpenFileName(this);
if(!fileName.isEmpty())
{
ui->sendButton->setEnabled(true);
ui->clientStatusLabel->setText(tr("打开文件%1成功").arg(fileName));
}
}
void Widget::on_openButton_clicked()
{
openFile();
}
void Widget::send() //连接服务器
{
qDebug() << "send()" << endl;
ui->sendButton->setEnabled(false);
bytesWrinten = 0; //初始化已发送字节为0
ui->clientStatusLabel->setText(tr("正在连接c..."));
tcpClient->connectToHost(ui->hostLineEdit->text(),
ui->portLineEdit->text().toInt()); //连接
}
void Widget::startTransfer() //实现文件大小等信息的发送
{
qDebug() << "startTransfer()" << endl;
localFile = new QFile(fileName);
if(!localFile->open(QFile::ReadOnly))
{
qDebug()<<"open file error!";
return;
}
totalBytes = localFile->size();
//文件总大小
QDataStream sendOut(&outBlock,QIODevice::WriteOnly);
sendOut.setVersion(QDataStream::Qt_5_3);
QString currentFileName = fileName.right(fileName.size() -
fileName.lastIndexOf('/')-1);
sendOut << qint64(0) << qint64(0) << currentFileName;
//这里总大小是总大小信息、文件大小信息、文件名和实际文件大小的总和
totalBytes += outBlock.size();
sendOut.device()->seek(0);
//返回outBolock的开始,用实际的大小信息代替两个qint64(0)空间
sendOut<<totalBytes<<qint64((outBlock.size() - sizeof(qint64)*2));
//发送完头数据后剩余数据的大小
bytesToWrite = totalBytes - tcpClient->write(outBlock);
ui->clientStatusLabel->setText(tr("已连接!"));
outBlock.resize(0);
}
//更新进度条,实现文件的传送
void Widget::updataClientProgress(qint64 numBytes)
{
qDebug() << "updataClientProgress()" << endl;
bytesWrinten += (int)numBytes;
//已经发送数据的大小
if(bytesToWrite > 0) //如果已经发送了数据
{
outBlock = localFile->read(qMin(bytesToWrite,loadSize));
//每次发送loadSize 大小的数据,这里设置为4KB,如果剩余的数据不足4KB
//就发送剩余数据的大小
bytesToWrite -= (int)tcpClient->write(outBlock);
//发送完一次数据后还剩余数据的大小
outBlock.resize(0);
//清空发送缓冲区
}
else
{
localFile->close();//如果没有发送任何数据,则关闭文件
}
ui->clientprogressBar->setMaximum(totalBytes);
ui->clientprogressBar->setValue(bytesWrinten);
//更新进度条
if(bytesWrinten == totalBytes) //发送完毕
{
ui->clientStatusLabel->setText(tr("发送文件 %1 成功!").arg(fileName));
localFile->close();
tcpClient->close();
}
}
//显示错误
void Widget::displayError(QAbstractSocket::SocketError)
{
qDebug() << "displayError()" << endl;
qDebug() << tcpClient->errorString();
tcpClient->close();
ui->clientprogressBar->reset();
ui->clientStatusLabel->setText(tr("Client Ready"));
ui->sendButton->setEnabled(true);
}
void Widget::on_sendButton_clicked()
{
qDebug() << "on_sendButton_clicked()" << endl;
send();
}