欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

QT實現(xiàn)文件傳輸功能

 更新時間:2022年08月18日 16:30:31   作者:我是黏黏蟲  
這篇文章主要為大家詳細介紹了QT實現(xiàn)文件傳輸功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例為大家分享了QT實現(xiàn)文件傳輸功能的具體代碼,供大家參考,具體內(nèi)容如下

過程如下:

1、服務器端設(shè)置監(jiān)聽套接字,開始監(jiān)聽;

2、客戶端在連接成功時開始傳送文件,有connected()信號連接send()槽,send()發(fā)送文件頭信息,包括文件名、文件總大小和文件名大小等;

3、傳送完文件頭信息時開始傳送文件內(nèi)容,有bytesWritten(qint64)信號連接到goOnSend(qint64)槽,前者是當想套接字寫入數(shù)據(jù)時會出發(fā)的信號,即當已經(jīng)想套接字寫入數(shù)據(jù),就繼續(xù)傳送數(shù)據(jù),有send()傳送文件頭信息開始觸發(fā),直到文件傳完為止。

4、在服務器端,首先接收文件頭信息,然后讀取文件名來用新建文件的方式打開一個文件,然后讀取文件名即文件等大小信息,用來更新進度條和繼續(xù)接收數(shù)據(jù);

5、實現(xiàn)循環(huán)傳輸,在客戶端,因為第一次send()是由connected()信號觸發(fā)的,之后的每次傳送應該手動調(diào)用send();在服務器端,在有新數(shù)據(jù)到達時,會判斷是否為頭文件,因此在每次文件傳完的時候?qū)yteReceived重置為0,即下一次再接收到數(shù)據(jù)的時候依據(jù)byteReceived判斷的結(jié)果就是一個新文件了。

客戶端代碼:

#ifndef WIDGET_H ?
#define WIDGET_H ?
??
#include <QWidget> ?
#include <QTcpSocket> ?
#include <QFile> ?
#include <string> ?
??
namespace Ui { ?
class Widget; ?
} ?
??
class Widget : public QWidget ?
{ ?
? ? Q_OBJECT ?
??
public: ?
? ? explicit Widget(QWidget *parent = 0); ?
? ? ~Widget(); ?
? ? ??
private: ?
? ? Ui::Widget *ui; ?
??
? ? QTcpSocket *tcpClient; ?
? ? QFile *localFile; ?
? ? QString fileName; ?//文件名 ?
??
? ? QByteArray outBlock; ?//分次傳 ?
? ? qint64 loadSize; ?//每次發(fā)送數(shù)據(jù)的大小 ?
? ? qint64 byteToWrite; ?//剩余數(shù)據(jù)大小 ?
? ? qint64 totalSize; ?//文件總大小 ?
??
? ? int sendTimes; ?//用來標記是否為第一次發(fā)送,第一次以后連接信號觸發(fā),后面的則手動調(diào)用 ?
??
private slots: ?
? ? void send(); ?//傳送文件頭信息 ?
? ? void goOnSend(qint64); ?//傳送文件內(nèi)容 ?
? ? void on_openPushButton_clicked(); ?
? ? void on_sendPushButton_clicked(); ?
}; ?
??
#endif // WIDGET_H ?

widget.cpp

#include "widget.h" ?
#include "ui_widget.h" ?
#include <QHostAddress> ?
#include <QTextCodec> ?
#include <QFileDialog> ?
??
Widget::Widget(QWidget *parent) : ?
? ? QWidget(parent), ?
? ? ui(new Ui::Widget) ?
{ ?
? ? ui->setupUi(this); ?
??
? ? ui->progressLabel->hide(); ?
? ? QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF8"));
??
? ? tcpClient = new QTcpSocket(this); ?
? ? sendTimes = 0; ?
??
? ? connect(tcpClient, SIGNAL(connected()), this, SLOT(send())); ?//當連接成功時,就開始傳送文件 ?
? ? connect(tcpClient, SIGNAL(bytesWritten(qint64)), this, SLOT(goOnSend(qint64))); ??
} ?
??
void Widget::send() ?//發(fā)送文件頭信息 ?
{ ?
? ? byteToWrite = localFile->size(); ?//剩余數(shù)據(jù)的大小 ?
? ? totalSize = localFile->size(); ?
??
? ? loadSize = 4*1024; ?//每次發(fā)送數(shù)據(jù)的大小 ?
??
? ? QDataStream out(&outBlock, QIODevice::WriteOnly); ?
? ? QString currentFileName = fileName.right(fileName.size() - fileName.lastIndexOf('/')-1); ?
??
? ? out<<qint64(0)<<qint64(0)<<currentFileName; ?
??
? ? totalSize += outBlock.size(); ?//總大小為文件大小加上文件名等信息大小 ?
? ? byteToWrite += outBlock.size(); ?
??
? ? out.device()->seek(0); ?//回到字節(jié)流起點來寫好前面連個qint64,分別為總大小和文件名等信息大小 ?
? ? out<<totalSize<<qint64(outBlock.size()); ?
??
? ? tcpClient->write(outBlock); ?//將讀到的文件發(fā)送到套接字 ?
??
? ? ui->progressLabel->show(); ?
? ? ui->sendProgressBar->setMaximum(totalSize); ?
? ? ui->sendProgressBar->setValue(totalSize - byteToWrite); ?
} ?
??
void Widget::goOnSend(qint64 numBytes) ?//開始發(fā)送文件內(nèi)容 ?
{ ?
? ? byteToWrite -= numBytes; ?//剩余數(shù)據(jù)大小 ?
? ? outBlock = localFile->read(qMin(byteToWrite, loadSize)); ?
? ? tcpClient->write(outBlock); ?
??
? ? ui->sendProgressBar->setMaximum(totalSize); ?
? ? ui->sendProgressBar->setValue(totalSize - byteToWrite); ?
??
? ? if(byteToWrite == 0) ?//發(fā)送完畢 ?
? ? ? ? ui->sendStatusLabel->setText(tr("文件發(fā)送完畢!")); ?
} ?
??
Widget::~Widget() ?
{ ?
? ? delete ui; ?
} ?
??
void Widget::on_openPushButton_clicked() ?//打開文件并獲取文件名(包括路徑) ?
{ ?
? ? ui->sendStatusLabel->setText(tr("正在打開文件...")); ?
? ? ui->sendProgressBar->setValue(0); ?//非第一次發(fā)送 ?
??
? ? loadSize = 0; ?
? ? byteToWrite = 0; ?
? ? totalSize = 0; ?
? ? outBlock.clear(); ?
??
? ? fileName = QFileDialog::getOpenFileName(this); ?
? ? localFile = new QFile(fileName); ?
? ? localFile->open(QFile::ReadOnly); ?
??
? ? ui->sendStatusLabel->setText(tr("已打開文件 %1").arg(fileName)); ?
} ?
??
void Widget::on_sendPushButton_clicked() ?
{ ?
? ? if(sendTimes == 0) ?//只有第一次發(fā)送的時候,是發(fā)生在連接產(chǎn)生信號connect時 ?
? ? { ?
? ? ? ? tcpClient->connectToHost(QHostAddress("192.168.1.137"), 1000); ?
? ? ? ? sendTimes = 1; ? ?
? ? } ?
? ? else ?
? ? ? ? send(); ?//第一次發(fā)送的時候是由connectToHost出發(fā)connect信號才能調(diào)用send,第二次之后就需要調(diào)用send了 ?
??
? ? ui->sendStatusLabel->setText(tr("正在發(fā)送文件 %1").arg(fileName)); ?
} ?

服務端代碼:

widget.h

#ifndef WIDGET_H ?
#define WIDGET_H ?
??
#include <QWidget> ?
#include <QtNetwork/QTcpServer> ?
#include <QtNetwork/QTcpSocket> ?
#include <QFile> ?
#include <QString> ?
??
namespace Ui { ?
class Widget; ?
} ?
??
class Widget : public QWidget ?
{ ?
? ? Q_OBJECT ?
? ? ??
public: ?
? ? explicit Widget(QWidget *parent = 0); ?
? ? ~Widget(); ?
? ? ??
private: ?
? ? Ui::Widget *ui; ?
??
? ? QTcpServer *server; ?
? ? QTcpSocket *receivedSocket; ?
? ? QFile *newFile; ?
??
? ? QByteArray inBlock; ?
? ? QString fileName; ?
? ? qint64 totalSize; ?//總共需要發(fā)送的文件大?。ㄎ募?nèi)容&文件名信息) ?
? ? qint64 byteReceived; ?//已經(jīng)發(fā)送的大小 ?
??
private slots: ?
? ? void acceptConnection(); ?
? ? void readClient(); ?
? ? void on_pushButton_clicked(); ?
}; ?
??
#endif // WIDGET_H ?

widget.cpp

#include "widget.h" ?
#include "ui_widget.h" ?
#include <QTextCodec> ?
??
Widget::Widget(QWidget *parent) : ?
? ? QWidget(parent), ?
? ? ui(new Ui::Widget) ?
{ ?
? ? ui->setupUi(this); ?
? ? ui->progressLabel->hide(); ??
? ? QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF8"));
} ?
??
void Widget::acceptConnection() ?
{ ?
? ? ui->receivedStatusLabel->setText(tr("已連接,正在準備接收文件!")); ?
??
? ? receivedSocket = server->nextPendingConnection(); ?
? ? connect(receivedSocket, SIGNAL(readyRead()), this, SLOT(readClient())); ?
} ?
??
void Widget::readClient() ?
{ ?
? ? ui->receivedStatusLabel->setText(tr("正在接收文件...")); ?
??
? ? if(byteReceived == 0) ?//才剛開始接收數(shù)據(jù),此數(shù)據(jù)為文件信息 ?
? ? { ?
? ? ? ? ui->receivedProgressBar->setValue(0); ?
??
? ? ? ? QDataStream in(receivedSocket); ?
? ? ? ? in>>totalSize>>byteReceived>>fileName; ? ?
? ? ? ? newFile = new QFile(fileName); ?
? ? ? ? newFile->open(QFile::WriteOnly); ?
? ? } ?
? ? else ?//正式讀取文件內(nèi)容 ?
? ? { ?
? ? ? ? inBlock = receivedSocket->readAll(); ?
??
? ? ? ? byteReceived += inBlock.size(); ?
? ? ? ? newFile->write(inBlock); ?
? ? ? ? newFile->flush(); ?
? ? } ??
? ? ui->progressLabel->show(); ?
? ? ui->receivedProgressBar->setMaximum(totalSize); ?
? ? ui->receivedProgressBar->setValue(byteReceived); ?
??
? ? if(byteReceived == totalSize) ?
? ? { ?
? ? ? ? ui->receivedStatusLabel->setText(tr("%1接收完成").arg(fileName)); ?
??
? ? ? ? inBlock.clear(); ?
? ? ? ? byteReceived = 0; ?
? ? ? ? totalSize = 0; ?
? ? } ?
} ?
??
Widget::~Widget() ?
{ ?
? ? delete ui; ?
} ??
void Widget::on_pushButton_clicked() ?
{ ?
? ? totalSize = 0; ?
? ? byteReceived = 0; ?
??
? ? server = new QTcpServer(this); ?
? ? server->listen(QHostAddress("192.168.1.137"), 1000); ?
??
? ? connect(server, SIGNAL(newConnection()), this, SLOT(acceptConnection())); ?
??
? ? ui->receivedProgressBar->setValue(0); ?
? ? ui->receivedStatusLabel->setText(tr("開始監(jiān)聽...")); ?
}?

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論