<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
本文範例為大家分享了QT實現檔案傳輸功能的具體程式碼,供大家參考,具體內容如下
過程如下:
1、伺服器端設定監聽通訊端,開始監聽;
2、使用者端在連線成功時開始傳送檔案,有connected()訊號連線send()槽,send()傳送檔案頭資訊,包括檔名、檔案總大小和檔名大小等;
3、傳送完檔案頭資訊時開始傳送檔案內容,有bytesWritten(qint64)訊號連線到goOnSend(qint64)槽,前者是當想通訊端寫入資料時會出發的訊號,即當已經想通訊端寫入資料,就繼續傳送資料,有send()傳送檔案頭資訊開始觸發,直到檔案傳完為止。
4、在伺服器端,首先接收檔案頭資訊,然後讀取檔名來用新建檔案的方式開啟一個檔案,然後讀取檔名即檔案等大小資訊,用來更新進度條和繼續接收資料;
5、實現迴圈傳輸,在使用者端,因為第一次send()是由connected()訊號觸發的,之後的每次傳送應該手動呼叫send();在伺服器端,在有新資料到達時,會判斷是否為標頭檔案,因此在每次檔案傳完的時候將byteReceived重置為0,即下一次再接收到資料的時候依據byteReceived判斷的結果就是一個新檔案了。
#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; //每次傳送資料的大小 qint64 byteToWrite; //剩餘資料大小 qint64 totalSize; //檔案總大小 int sendTimes; //用來標記是否為第一次傳送,第一次以後連線訊號觸發,後面的則手動呼叫 private slots: void send(); //傳送檔案頭資訊 void goOnSend(qint64); //傳送檔案內容 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() //傳送檔案頭資訊 { byteToWrite = localFile->size(); //剩餘資料的大小 totalSize = localFile->size(); loadSize = 4*1024; //每次傳送資料的大小 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); //回到位元組流起點來寫好前面連個qint64,分別為總大小和檔名等資訊大小 out<<totalSize<<qint64(outBlock.size()); tcpClient->write(outBlock); //將讀到的檔案傳送到通訊端 ui->progressLabel->show(); ui->sendProgressBar->setMaximum(totalSize); ui->sendProgressBar->setValue(totalSize - byteToWrite); } void Widget::goOnSend(qint64 numBytes) //開始傳送檔案內容 { byteToWrite -= numBytes; //剩餘資料大小 outBlock = localFile->read(qMin(byteToWrite, loadSize)); tcpClient->write(outBlock); ui->sendProgressBar->setMaximum(totalSize); ui->sendProgressBar->setValue(totalSize - byteToWrite); if(byteToWrite == 0) //傳送完畢 ui->sendStatusLabel->setText(tr("檔案傳送完畢!")); } Widget::~Widget() { delete ui; } void Widget::on_openPushButton_clicked() //開啟檔案並獲取檔名(包括路徑) { ui->sendStatusLabel->setText(tr("正在開啟檔案...")); ui->sendProgressBar->setValue(0); //非第一次傳送 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) //只有第一次傳送的時候,是發生在連線產生訊號connect時 { tcpClient->connectToHost(QHostAddress("192.168.1.137"), 1000); sendTimes = 1; } else send(); //第一次傳送的時候是由connectToHost出發connect訊號才能呼叫send,第二次之後就需要呼叫send了 ui->sendStatusLabel->setText(tr("正在傳送檔案 %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; //總共需要傳送的檔案大小(檔案內容&檔名資訊) qint64 byteReceived; //已經傳送的大小 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) //才剛開始接收資料,此資料為檔案資訊 { ui->receivedProgressBar->setValue(0); QDataStream in(receivedSocket); in>>totalSize>>byteReceived>>fileName; newFile = new QFile(fileName); newFile->open(QFile::WriteOnly); } else //正式讀取檔案內容 { 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("開始監聽...")); }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45