日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Qt多文件传输功能实现及方法概述

發布時間:2023/12/10 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Qt多文件传输功能实现及方法概述 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Qt多文件傳輸功能實現

    • 前言
    • 代碼實現概述
      • 客戶端代碼實現
      • 服務端代碼
      • 效果展示
    • 結論

前言

本次設計主要是為了功能上的實現,因此對于ui界面的設計都是怎么簡單怎么來的,主要的功能就是實現多個文件的發送與接收,即客戶端發送,服務端接收保存,并且刪去客戶端的已發送的文件。

代碼實現概述

這里就不在概述tcp通信的相關的內容,主要圍繞本文設計進行敘述:
第一就是文件發送的流程圖,單次文件內容發送主要分為兩次,首先是文件名,可用于服務端建立新的文件;其次是文件大小,可用服務端判斷是否完全接收完;最后是文件地址,用于服務端刪除客戶端發送的文件,也可以把這認為是簡單的協議:

第二就是多文件的發送:這里用到了QFileDialog類的getOpenFileNames函數(可以固定打開文件的類型),返回QStringList的文件路徑集合,接下來就是遍歷發送。
第三就是防止發生粘包的情況,使用QIODevice類waitForBytesWritten函數,每次等待數據內容發送。

客戶端代碼實現

tcpclient.h文件:

#ifndef TCPCLIENT_H #define TCPCLIENT_H#include <QtWidgets/QMainWindow> #include "ui_tcpclient.h" #include <QHostAddress> #include <QFile> #include <QTcpSocket>class TcpClient : public QMainWindow {Q_OBJECTpublic:TcpClient(QWidget *parent = 0);~TcpClient();void sendData();private:Ui::TcpClientClass ui;int port;QString ip;QTcpSocket *tcpSocket; //服務端連接套接字QFile locFile; //待發送的文件QList<QString> fileNames;QList<QString> paths;QList<qint64> fileSizes;qint64 sendSize;int sendTime;private slots:void slotSend(); //發送void slotOpen(); //打開文件void sendMessage(); //傳輸文件void sendData(int); };#endif // TCPCLIENT_H

tcpclient.cpp文件:

#include "tcpclient.h" #include <QFileDialog> #include <QtDebug> #include <QFileInfo>TcpClient::TcpClient(QWidget *parent): QMainWindow(parent) {ui.setupUi(this);//初始化port = 8081;ip = "127.0.0.1";connect(ui.openButton,SIGNAL(clicked()),this,SLOT(slotOpen()));connect(ui.sendButton,SIGNAL(clicked()),this,SLOT(slotSend()));connect(ui.closeButton,SIGNAL(clicked()),this,SLOT(close()));ui.openButton->setEnabled(true);ui.sendButton->setEnabled(false); }TcpClient::~TcpClient() {}void TcpClient::slotOpen() {//初始化數據fileNames.clear();fileSizes.clear();sendTime = 0;paths = QFileDialog::getOpenFileNames(this,"open file"); //當前目錄下if (!paths.isEmpty()){for (int i = 0; i < paths.size(); i++){locFile.setFileName(paths[i]);if (locFile.open(QIODevice::ReadOnly)){//獲取發送文件的信息QFileInfo info(paths[i]);fileNames.append(info.fileName()); //文件名fileSizes.append(info.size()); //文件大小}qDebug()<<"fileName:"<<fileNames[i]<<"fileSize:"<<fileSizes[i]<<"path:"<<paths[i];}}ui.sendButton->setEnabled(true); }void TcpClient::slotSend() {//創建連接服務器tcpSocket = new QTcpSocket(this);tcpSocket->connectToHost(ip,port); //連接服務器,并發出connected()信號connect(tcpSocket,SIGNAL(connected()),this,SLOT(sendMessage())); //傳輸文件槽函數 }void TcpClient::sendMessage() {qDebug()<<"link successful";ui.sendButton->setEnabled(false);//先發送頭,自定義組包, 文件名#文件大小,不是文件數據locFile.setFileName(paths[sendTime]);locFile.open(QIODevice::ReadOnly);QString head = QString("head#%1#%2#%3").arg(fileNames[sendTime]).arg(fileSizes[sendTime]).arg(paths[sendTime]);qDebug()<<"head:"<<head<<endl<<head.size();//發送頭qint64 len = tcpSocket->write(head.toUtf8().data());tcpSocket->waitForBytesWritten(); //等待數據內容發送if (len > 0){sendData(sendTime); //發送內容數據} }void TcpClient::sendData(int i) {QByteArray buf = locFile.readAll();qint64 len = tcpSocket->write(buf);tcpSocket->waitForBytesWritten(); //等待數據內容發送sendSize = len;qDebug()<<"sendSize:"<<sendSize;if (sendSize == fileSizes[i]){qDebug()<<"send successful";locFile.close();tcpSocket->close();}if (i < paths.size()-1){slotSend();sendTime++;} }

服務端代碼

因為服務端的代碼也比較簡單,這里就不展示了。

效果展示

因為只是簡單的功能設計,因此沒有直觀的展示,主要是客戶端的發送截圖,以及服務端對接收二進制文件內容的打印。
客戶端界面:

服務端控制臺打印文件內容:

結論

本次設計對單次文件傳輸是沒什么問題的,主要的多文件傳輸時的粘包現象,本次設計經過驗證對于多個小文件傳輸是沒問題的,但是不排除大量的大文件不會出現問題。因此就需要一個更好更穩定的協議來保證,這次只是簡單使用了等待傳輸的函數,后面我也會進一步進行更好的封包與解包的通信操作。見TCP解決粘包問題(結構數據封包拆包)

總結

以上是生活随笔為你收集整理的Qt多文件传输功能实现及方法概述的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。