最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

過(guò)程如下:

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

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

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

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

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

客戶端代碼:

#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; ?//用來(lái)標(biāo)記是否為第一次發(fā)送,第一次以后連接信號(hào)觸發(fā),后面的則手動(dòng)調(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())); ?//當(dāng)連接成功時(shí),就開始傳送文件 ?
? ? 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é)流起點(diǎn)來(lái)寫好前面連個(gè)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ā)送的時(shí)候,是發(fā)生在連接產(chǎn)生信號(hào)connect時(shí) ?
? ? { ?
? ? ? ? tcpClient->connectToHost(QHostAddress("192.168.1.137"), 1000); ?
? ? ? ? sendTimes = 1; ? ?
? ? } ?
? ? else ?
? ? ? ? send(); ?//第一次發(fā)送的時(shí)候是由connectToHost出發(fā)connect信號(hào)才能調(diào)用send,第二次之后就需要調(diào)用send了 ?
??
? ? ui->sendStatusLabel->setText(tr("正在發(fā)送文件 %1").arg(fileName)); ?
} ?

服務(wù)端代碼:

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("已連接,正在準(zhǔn)備接收文件!")); ?
??
? ? 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)聽...")); ?
}?

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • C++數(shù)組模擬之單鏈表與雙鏈表和棧和隊(duì)列的實(shí)現(xiàn)過(guò)程

    C++數(shù)組模擬之單鏈表與雙鏈表和棧和隊(duì)列的實(shí)現(xiàn)過(guò)程

    這篇文章主要介紹了C++數(shù)組模擬之單鏈表與雙鏈表和棧和隊(duì)列的實(shí)現(xiàn)過(guò)程,了解內(nèi)部原理是為了幫助我們做擴(kuò)展,同時(shí)也是驗(yàn)證了一個(gè)人的學(xué)習(xí)能力,如果你想讓自己的職業(yè)道路更上一層樓,這些底層的東西你是必須要會(huì)的,跟隨下文來(lái)具體了解吧
    2023-02-02
  • C++JSON庫(kù)CJsonObject詳解(輕量簡(jiǎn)單好用)

    C++JSON庫(kù)CJsonObject詳解(輕量簡(jiǎn)單好用)

    CJsonObject是基于cJSON全新開發(fā)一個(gè)C++版的JSON庫(kù),CJsonObject的最大優(yōu)勢(shì)是輕量簡(jiǎn)單好用,開發(fā)效率極高,對(duì)多層嵌套json的讀取和生成使用非常簡(jiǎn)單,喜歡的朋友一起看看吧
    2021-04-04
  • Qt中QGroupBox控件的實(shí)現(xiàn)

    Qt中QGroupBox控件的實(shí)現(xiàn)

    QGroupBox 是 Qt 框架中一個(gè)非常有用的控件,它主要用于組織和管理一組相關(guān)的控件,本文主要介紹了Qt中QGroupBox控件的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-04-04
  • C語(yǔ)言各種符號(hào)的使用介紹下篇

    C語(yǔ)言各種符號(hào)的使用介紹下篇

    C?語(yǔ)言的基本符號(hào)就有?20?多個(gè),每個(gè)符號(hào)可能同時(shí)具有多重含義,而且這些符號(hào)之間相互組合又使得?C?語(yǔ)言中的符號(hào)變得更加復(fù)雜起來(lái)
    2022-08-08
  • 舉例說(shuō)明自定義C++異常處理的實(shí)例

    舉例說(shuō)明自定義C++異常處理的實(shí)例

    這篇文章主要介紹了舉例說(shuō)明自定義C++異常處理的實(shí)例的相關(guān)資料,這里舉例說(shuō)明該如何使用C++ 的異常,需要的朋友可以參考下
    2017-10-10
  • C++lambda表達(dá)式使用介紹

    C++lambda表達(dá)式使用介紹

    Lambda 表達(dá)式(lambda expression)是一個(gè)匿名函數(shù),Lambda表達(dá)式基于數(shù)學(xué)中的λ演算得名。本文就來(lái)為大家詳細(xì)講講C++中Lambda表達(dá)式的使用,需要的可以參考一下
    2022-08-08
  • C++小知識(shí):C/C++中不要按值傳遞數(shù)組

    C++小知識(shí):C/C++中不要按值傳遞數(shù)組

    今天小編就為大家分享一篇關(guān)于C++小知識(shí):C/C++中不要按值傳遞數(shù)組,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-01-01
  • C++中單鏈表操作的示例代碼

    C++中單鏈表操作的示例代碼

    這篇文章主要為大家詳細(xì)介紹了C++中單鏈表操作的示例代碼,主要包括單鏈表的創(chuàng)建、元素的插入和刪除等。文中的代碼簡(jiǎn)潔易懂,需要的可以參考一下
    2022-10-10
  • C語(yǔ)言操作符進(jìn)階教程(表達(dá)式求值隱式類型轉(zhuǎn)換方法)

    C語(yǔ)言操作符進(jìn)階教程(表達(dá)式求值隱式類型轉(zhuǎn)換方法)

    這篇文章主要為大家介紹了C語(yǔ)言操作符進(jìn)階教程(表達(dá)式求值隱式類型轉(zhuǎn)換方法)
    2022-02-02
  • 用typedef定義類型詳細(xì)總結(jié)

    用typedef定義類型詳細(xì)總結(jié)

    用typedef可以聲明各種類型名,但不能用來(lái)定義變量,用typedef可以聲明數(shù)組類型、字符串類型、使用比較方便
    2013-10-10

最新評(píng)論

武陟县| 瑞安市| 阿城市| 高碑店市| 姚安县| 乐陵市| 宁陕县| 玉龙| 赤水市| 读书| 饶河县| 上饶县| 东平县| 宜黄县| 崇礼县| 新郑市| 武义县| 武安市| 平定县| 云林县| 蓝山县| 深水埗区| 丹巴县| 招远市| 健康| 利津县| 五原县| 郧西县| 涪陵区| 青浦区| 邹城市| 新巴尔虎左旗| 淮滨县| 花莲县| 台湾省| 梁平县| 澄迈县| 廉江市| 乌什县| 霍林郭勒市| 麻阳|