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

基于QT實現(xiàn)文件上傳和下載功能

 更新時間:2022年08月18日 16:55:56   作者:skynetkang  
這篇文章主要為大家詳細介紹了基于QT實現(xiàn)文件上傳和下載功能,支持斷點續(xù)傳,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例為大家分享了基于QT實現(xiàn)文件上傳和下載的具體代碼,供大家參考,具體內容如下

功能

  • 支持文件上傳功能
  • 支持文件下載功能
  • 支持斷點續(xù)傳功能
  • 支持連續(xù)多個文件的上傳下載

文件上傳下載流程

在確認斷點的時候會利用md5進行數(shù)據(jù)校驗,防止數(shù)據(jù)發(fā)生更改。

服務端

  • 采用多線程的Reactor模式。即一個線程對應多個filesocket進行文件上傳下載。線程個數(shù)可設置,默認為1.
  • FileServer 繼承QTcpServer,實現(xiàn)incomingConnection虛函數(shù)。當有新的連接到來時,會創(chuàng)建FileSocket并采用moveToThread接口,將其移入到當前活躍socket數(shù)量最少的線程中。
  • FileSocket采用Qt本身的事件循環(huán)和信號槽機制進行數(shù)據(jù)傳輸。通過設置兩者的交互機制,避免了tcp的粘包問題以及QTcpSocket的readyRead信號觸發(fā)問題。

服務端代碼:

//fileserver.h
#ifndef FILESERVER_H
#define FILESERVER_H

#include <QObject>
#include <QTcpServer>
#include <QAbstractSocket>
#include <QTcpSocket>
#include <QMap>
#include <QString>
#include <QThread>

class FileServer : public QTcpServer
{
? ? Q_OBJECT
public:
? ? explicit FileServer(QString param_server_name,quint8 param_thread_count=1,QObject *parent = nullptr);
? ? ~FileServer();

? ? QString getServername() {return m_server_name;}
? ? quint8 getThreadCount() {return m_thread_count;}
? ? //獲取當前每個線程的活躍socket數(shù)量
? ? void threadMonitor(QMap<qint32,quint32>& param_info);

signals:

public slots:
?? ?//開始監(jiān)聽
? ? bool run(quint16 port);
? ? void socketClose(qint32 id);

protected:
? ? void incomingConnection(qintptr socketDescriptor);

? ? struct ThreadInfo //線程信息,包括標志線程的ID和活躍socket的數(shù)量
? ? {
? ? ? ? qint32 id;
? ? ? ? QThread msg_thread;
? ? ? ? quint32 active_count;
? ? };
? ? //獲取活躍socket數(shù)量最小的線程id
? ? qint32 getMinActiveThread();

private:
? ? QString m_server_name;
? ? quint8 m_thread_count;
? ? ThreadInfo* m_socket_thread;

};


//fileserver.cpp
#include "fileserver.h"
#include "filesocket.h"

#include <QTcpSocket>
#include <QHostAddress>

FileServer::FileServer(QString param_server_name,quint8 param_thread_count,QObject *parent) :
? ? QTcpServer(parent),
? ? m_server_name(param_server_name),
? ? m_thread_count(param_thread_count)
{
?? ?//根據(jù)用戶給定的線程個數(shù)進行線程信息數(shù)組的申請,并進行初始化
? ? this->m_socket_thread=new ThreadInfo[this->m_thread_count];
? ? for(qint32 index=0;index<this->m_thread_count;index++)
? ? {
? ? ? ? this->m_socket_thread[index].id=index;
? ? ? ? this->m_socket_thread[index].active_count=0;
? ? ? ? //啟動線程
? ? ? ? this->m_socket_thread[index].msg_thread.start();
? ? }
}

FileServer::~FileServer()
{
? ? if(this->isListening())
? ? {
? ? ? ? this->close();
? ? }
?? ?
?? ?//釋放申請的線程信息數(shù)組
? ? delete [] this->m_socket_thread;
? ? this->m_socket_thread=nullptr;
}

void FileServer::threadMonitor(QMap<qint32, quint32>& param_info)
{
? ? for(qint32 index=0;index<this->m_thread_count;index++)
? ? {
? ? ? ? param_info[index]=this->m_socket_thread[index].active_count;
? ? }
}

bool FileServer::run(quint16 port)
{
? ? if(this->isListening())
? ? {
? ? ? ? qDebug()<<"port("<<port<<")already listen,please close first."<<endl;
? ? ? ? return true;
? ? }

? ? if(this->listen(QHostAddress::Any,port))
? ? {
? ? ? ? qDebug()<<"listen "<<this->m_server_name<<"port("<<port<<") successful."<<endl;
? ? ? ? return true;
? ? }
? ? else
? ? {
? ? ? ? qDebug()<<"listen "<<"port("<<port<<") failed,please check the network port."<<endl;
? ? ? ? return false;
? ? }
}

void FileServer::socketClose(qint32 id)
{
?? ?//槽函數(shù),socket關閉的時候,將對應的線程的活躍socket數(shù)量減一
? ? this->m_socket_thread[id].active_count--;
}

void FileServer::incomingConnection(qintptr socketDescriptor)
{
? ? qDebug()<<"new client connection:"<<socketDescriptor<<endl;
? ? qint32 thread_id=this->getMinActiveThread();
? ? //建立新的socket
? ? FileSocket* new_socket=new FileSocket(this->m_socket_thread[thread_id].id,socketDescriptor);
? ? connect(new_socket,SIGNAL(socketClose(qint32)),this,SLOT(socketClose(qint32)));
? ? //移入到線程中運行
? ? new_socket->moveToThread(&(this->m_socket_thread[thread_id].msg_thread));
? ? this->m_socket_thread[thread_id].active_count++;
}

qint32 FileServer::getMinActiveThread()
{
? ? qint32 min_id=0;
? ? for(qint32 index=1;index<this->m_thread_count;index++)
? ? {
? ? ? ? if(this->m_socket_thread[min_id].active_count>this->m_socket_thread[index].active_count)
? ? ? ? {
? ? ? ? ? ? min_id=index;
? ? ? ? }
? ? }

? ? return min_id;
}

#endif // FILESERVER_H

filesocket

//filesocket.h
#ifndef FILESOCKET_H
#define FILESOCKET_H

#include <QObject>
#include <QAbstractSocket>
#include <QTcpSocket>
#include <QByteArray>
#include <QFile>

//文件上傳下載的字段定義
#define FILE_UPLOAD_HEADER ? ? ? ? ? ? 100
#define FILE_UPLOAD_POS ? ? ? ? ? ? ? ?101
#define FILE_UPLOAD_TAIL ? ? ? ? ? ? ? 103
#define FILE_DOWNLOAD_HEADER ? ? ? ? ? 200
#define FILE_DOWNLOAD_CONTENT ? ? ? ? ?202
#define FILE_DOWNLOAD_TAIL ? ? ? ? ? ? 203

//錯誤碼定義
#define OK ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0
#define FILE_WRITE_ERROR ? ? ? ? ? ? ? -1
#define FILE_OPEN_ERROR ? ? ? ? ? ? ? ?-2
#define FILE_SEEK_ERROR ? ? ? ? ? ? ? ?-3
#define FILE_ALREADY_EXISTS_ERROR ? ? ?-4
#define RECV_DATA_TIMEOUT_ERROR ? ? ? ?-5
#define RECV_UNKNOW_DATA_ERROR ? ? ? ? -6
#define CONNECT_SERVER_ERROR ? ? ? ? ? -7
#define UPLOAD_FILE_ERROR ? ? ? ? ? ? ?-8
#define DOWNLOAD_FILE_ERROR ? ? ? ? ? ?-10


class FileSocket : public QObject
{
? ? Q_OBJECT
public:
? ? explicit FileSocket(qint32 param_id,qintptr param_socketDescriptor,QObject *parent = nullptr);
? ? ~FileSocket();

signals:
? ? void socketClose(qint32); //當socket關閉的時候,向FileServer發(fā)送關閉信號

public slots:
? ? void socketError(QAbstractSocket::SocketError param_error);
? ? void socketDisconnect();
? ??
? ? //綁定readyRead信號,進行數(shù)據(jù)讀取
? ? void fileRead();
? ??
? ? //文件數(shù)據(jù)處理
? ? void fileHandle(qint64 param_request_id,QMap<QString,QVariant>& param_qst_file,QMap<QString,QVariant>& param_rst_file,bool& reply);

protected:
? ? void paramInit();
? ? qint64 fileUploadHeader(QString filename,qint64& pos,QString& md5_value);
? ? qint64 fileUploadPos(qint64 file_pos);

? ? qint64 fileDownloadHeader(QString filename,qint64& pos,QString& md5_value,qint64& file_size);
? ? qint64 fileDownloadContent();

private:
? ? qint32 m_id;
? ? QTcpSocket m_socket;

? ? qint64 m_fileupload_state; //文件上傳中間狀態(tài)標志,分為頭尾處理狀態(tài)和文件數(shù)據(jù)傳輸狀態(tài)。
? ? qint64 m_file_totalBytes;
? ? qint64 m_file_pos;
? ? qint64 m_req_id;

? ? QByteArray m_msgBytes;
? ? QFile m_local_file;
? ? qint64 m_status;
};
#endif // FILESOCKET_H

//filecosket.cpp
#include "filesocket.h"

#include <QDataStream>
#include <QByteArray>
#include <QMap>
#include <QVariant>
#include <QString>
#include <QCryptographicHash>

const QString g_root_dir=".";

FileSocket::FileSocket(qint32 param_id,qintptr param_socketDescriptor,QObject *parent) :
? ? QObject(parent),
? ? m_id(param_id),
? ? m_socket(this),
? ? m_fileupload_state(0),
? ? m_local_file(this)
{
? ? this->m_msgBytes.resize(0);
? ? this->paramInit();
? ? this->m_socket.setSocketDescriptor(param_socketDescriptor);

? ? connect(&(this->m_socket),SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(socketError(QAbstractSocket::SocketError)));
? ? //綁定readyRead信號,進行數(shù)據(jù)讀取
? ? connect(&(this->m_socket),SIGNAL(readyRead()),this,SLOT(fileRead()));
}

FileSocket::~FileSocket()
{

}

void FileSocket::socketError(QAbstractSocket::SocketError param_error)
{
? ? qDebug()<<"socket error("<<param_error<<"): "<<this->m_socket.errorString()<<endl;
? ? this->m_fileupload_state=0;
? ? this->socketDisconnect();
}

void FileSocket::socketDisconnect()
{
? ? this->m_socket.disconnectFromHost();
? ? emit socketClose(this->m_id);
? ? this->deleteLater();
}

void FileSocket::fileRead()
{
? ? this->m_msgBytes.resize(0);
? ? this->m_msgBytes=this->m_socket.readAll();
? ? if(this->m_fileupload_state==0)
? ? {
? ? ? ? QDataStream file_in(&this->m_msgBytes,QIODevice::ReadOnly);
? ? ? ? QMap<QString,QVariant> param_qst_file;
? ? ? ? file_in>>this->m_req_id>>param_qst_file;

? ? ? ? QByteArray paramBytes;
? ? ? ? bool reply=true;
? ? ? ? QMap<QString,QVariant> param_rst_file;
? ? ? ? this->fileHandle(this->m_req_id,param_qst_file,param_rst_file,reply);
? ? ? ? if(reply==true)
? ? ? ? {
? ? ? ? ? ? QDataStream msg_out(&paramBytes,QIODevice::WriteOnly);
? ? ? ? ? ? msg_out<<qint64(this->m_req_id)<<param_rst_file;
? ? ? ? ? ? this->m_socket.write(paramBytes);
? ? ? ? ? ? this->m_socket.waitForBytesWritten();
? ? ? ? }
? ? }
? ? else
? ? {
? ? ?? ?//文件上傳的時候,開始數(shù)據(jù)寫入
? ? ? ? this->m_file_totalBytes-=this->m_msgBytes.size();
? ? ? ? if(this->m_status!=OK)
? ? ? ? {
? ? ? ? ? ? return;
? ? ? ? }

? ? ? ? qint64 wrtieBytes=this->m_local_file.write(this->m_msgBytes);
? ? ? ? if(wrtieBytes==-1)
? ? ? ? {
? ? ? ? ? ? qDebug()<<"file write error"<<endl;
? ? ? ? ? ? this->m_status=FILE_WRITE_ERROR;
? ? ? ? ? ? return;
? ? ? ? }

? ? ? ? if(this->m_file_totalBytes==0)
? ? ? ? {
? ? ? ? ? ? this->m_local_file.close();
? ? ? ? ? ? QByteArray paramBytes;
? ? ? ? ? ? QMap<QString,QVariant> param_rst_file;
? ? ? ? ? ? param_rst_file[QString("reply_status")]=QVariant(this->m_status);

? ? ? ? ? ? QDataStream msg_out(&paramBytes,QIODevice::WriteOnly);
? ? ? ? ? ? msg_out<<qint64(FILE_UPLOAD_TAIL)<<param_rst_file;
? ? ? ? ? ? this->m_socket.write(paramBytes);
? ? ? ? ? ? this->m_socket.waitForBytesWritten();
? ? ? ? ? ? this->m_fileupload_state=0;
? ? ? ? }
? ? }
}

void FileSocket::fileHandle(qint64 param_request_id,QMap<QString,QVariant>& param_qst_file,QMap<QString,QVariant>& param_rst_file,bool& reply)
{
? ? switch (param_request_id)
? ? {
? ? case FILE_UPLOAD_HEADER:{
? ? ? ? this->paramInit();
? ? ? ? QString file_prjpath=param_qst_file[QString("file_prjpath")].toString();

? ? ? ? qint64 pos=0;
? ? ? ? QString md5_value;
? ? ? ? qint64 status=this->fileUploadHeader(file_prjpath,pos,md5_value);
? ? ? ? if(status==OK)
? ? ? ? {
? ? ? ? ? ? this->m_fileupload_state=0;
? ? ? ? }

? ? ? ? param_rst_file[QString("reply_status")]=QVariant(status);
? ? ? ? param_rst_file[QString("file_pos")]=QVariant(pos);
? ? ? ? param_rst_file[QString("file_md5")]=QVariant(md5_value);
? ? ? ? break;
? ? }
? ? case FILE_UPLOAD_POS:{

? ? ? ? qint64 file_pos=param_qst_file[QString("file_pos")].toInt();
? ? ? ? this->m_file_totalBytes=param_qst_file[QString("file_size")].toInt();

? ? ? ? qint64 status=this->fileUploadPos(file_pos);
? ? ? ? if(status==OK)
? ? ? ? {
? ? ? ? ? ? this->m_fileupload_state=1;
? ? ? ? }

? ? ? ? param_rst_file[QString("reply_status")]=QVariant(status);
? ? ? ? break;
? ? }
? ? case FILE_DOWNLOAD_HEADER:{
? ? ? ? this->paramInit();
? ? ? ? QString file_prjpath=param_qst_file[QString("file_prjpath")].toString();
? ? ? ? this->m_file_pos=param_qst_file[QString("file_pos")].toInt();
? ? ? ? QString file_md5_value=param_qst_file[QString("file_md5")].toString();

? ? ? ? qint64 status=this->fileDownloadHeader(file_prjpath,this->m_file_pos,file_md5_value,this->m_file_totalBytes);
? ? ? ? if(status==OK)
? ? ? ? {
? ? ? ? ? ? this->m_fileupload_state=0;
? ? ? ? }

? ? ? ? param_rst_file[QString("reply_status")]=QVariant(status);
? ? ? ? param_rst_file[QString("file_pos")]=QVariant(this->m_file_pos);
? ? ? ? param_rst_file[QString("file_size")]=QVariant(this->m_file_totalBytes);
? ? ? ? break;
? ? }
? ? case FILE_DOWNLOAD_CONTENT:{
? ? ? ? reply=false;
? ? ? ? this->fileDownloadContent();
? ? ? ? break;
? ? }
? ? case FILE_DOWNLOAD_TAIL:{
? ? ? ? qint64 status=OK;
? ? ? ? this->m_fileupload_state=0;
? ? ? ? param_rst_file[QString("reply_status")]=QVariant(status);
? ? ? ? break;
? ? }
? ? }
}

void FileSocket::paramInit()
{
? ? this->m_file_totalBytes=0;
? ? this->m_status=OK;
? ? this->m_file_pos=0;
}

qint64 FileSocket::fileUploadHeader(QString filename, qint64 &pos, QString &md5_value)
{
? ? QString filepath=QString("%1/%2").arg(g_root_dir).arg(filename);
? ? this->m_local_file.setFileName(filepath);
? ? if(this->m_local_file.exists()==false)
? ? {
? ? ? ? pos=0;
? ? ? ? return OK;
? ? }
? ? else
? ? {
? ? ? ? pos=this->m_local_file.size();
? ? ? ? if(pos==0)
? ? ? ? {
? ? ? ? ? ? return OK;
? ? ? ? }

? ? ? ? if(this->m_local_file.open(QIODevice::ReadOnly)==false)
? ? ? ? {
? ? ? ? ? ? ?pos=0;
? ? ? ? ? ? ?qDebug()<<"open file("<<this->m_local_file.fileName()<<") failed."<<endl;
? ? ? ? ? ? ?return FILE_OPEN_ERROR;
? ? ? ? }

? ? ? ? QCryptographicHash file_md5(QCryptographicHash::Md5);
? ? ? ? qint64 payloadSize=10*1024*1024;
? ? ? ? QByteArray file_data=this->m_local_file.read(payloadSize);
? ? ? ? while(!file_data.isEmpty())
? ? ? ? {
? ? ? ? ? ? file_md5.addData(file_data);
? ? ? ? ? ? file_data=this->m_local_file.read(payloadSize);
? ? ? ? }
? ? ? ? this->m_local_file.close();
? ? ? ? md5_value=QString(file_md5.result().toHex());

? ? ? ? return OK;
? ? }
}

qint64 FileSocket::fileUploadPos(qint64 file_pos)
{
? ? if(this->m_local_file.open(QIODevice::WriteOnly)==false)
? ? {
? ? ? ? qDebug()<<"open file("<<this->m_local_file.fileName()<<") failed."<<endl;
? ? ? ? return FILE_OPEN_ERROR;
? ? }

? ? if(this->m_local_file.seek(file_pos)==false)
? ? {
? ? ? ? qDebug()<<"seek file("<<this->m_local_file.fileName()<<") failed."<<endl;
? ? ? ? this->m_local_file.close();
? ? ? ? return FILE_SEEK_ERROR;
? ? }

? ? return OK;
}

qint64 FileSocket::fileDownloadHeader(QString filename, qint64 &pos, QString &md5_value, qint64 &file_size)
{
? ? this->m_local_file.setFileName(QString("%1/%2").arg(g_root_dir).arg(filename));
? ? if(this->m_local_file.open(QIODevice::ReadOnly)==false)
? ? {
? ? ? ? qDebug()<<"file open error"<<endl;
? ? ? ? return FILE_OPEN_ERROR;
? ? }
? ? file_size=this->m_local_file.size();

? ? if(pos==0)
? ? {
? ? ? ? this->m_local_file.close();
? ? ? ? return OK;
? ? }

? ? QCryptographicHash file_md5(QCryptographicHash::Md5);
? ? qint64 payloadSize=10*1024*1024;
? ? qint64 file_pos=pos;
? ? qint64 readBytes=0;
? ? while(file_pos>0)
? ? {
? ? ? ? readBytes=qMin(file_pos,payloadSize);
? ? ? ? QByteArray file_data=this->m_local_file.read(readBytes);
? ? ? ? file_md5.addData(file_data);
? ? ? ? file_pos-=readBytes;
? ? }
? ? this->m_local_file.close();

? ? if(QString(file_md5.result().toHex())!=md5_value)
? ? {
? ? ? ? pos=0;
? ? }
? ? file_size-=pos;

? ? return OK;
}

qint64 FileSocket::fileDownloadContent()
{
? ? if(this->m_local_file.open(QIODevice::ReadOnly)==false)
? ? {
? ? ? ? qDebug()<<"file open error"<<endl;
? ? ? ? return FILE_OPEN_ERROR;
? ? }
? ? this->m_local_file.seek(this->m_file_pos);

? ? qint64 payloadSize=1*1024*1024;
? ? while(this->m_file_totalBytes!=0)
? ? {
? ? ? ? QByteArray readData=this->m_local_file.read(qMin(this->m_file_totalBytes,payloadSize));
? ? ? ? this->m_file_totalBytes-=this->m_socket.write(readData);
? ? ? ? this->m_socket.waitForBytesWritten();
? ? }

? ? return OK;
}

客戶端

即支持單個文件和文件列表的上傳和下載,一個socket可連續(xù)進行文件的上傳和下載。

客戶端源碼

//fileclient.h
#ifndef FILECLIENT_H
#define FILECLIENT_H

#include <QObject>
#include <QAbstractSocket>
#include <QTcpSocket>
#include <QByteArray>
#include <QString>
#include <QStringList>
#include <QFile>

//文件上傳下載字段定義
#define FILE_UPLOAD_HEADER ? ? ? ? ? ? 100
#define FILE_UPLOAD_POS ? ? ? ? ? ? ? ?101
#define FILE_UPLOAD_TAIL ? ? ? ? ? ? ? 103
#define FILE_DOWNLOAD_HEADER ? ? ? ? ? 200
#define FILE_DOWNLOAD_CONTENT ? ? ? ? ?202
#define FILE_DOWNLOAD_TAIL ? ? ? ? ? ? 203

//錯誤碼定義
#define OK ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0
#define FILE_WRITE_ERROR ? ? ? ? ? ? ? -1
#define FILE_OPEN_ERROR ? ? ? ? ? ? ? ?-2
#define FILE_SEEK_ERROR ? ? ? ? ? ? ? ?-3
#define FILE_ALREADY_EXISTS_ERROR ? ? ?-4
#define RECV_DATA_TIMEOUT_ERROR ? ? ? ?-5
#define RECV_UNKNOW_DATA_ERROR ? ? ? ? -6
#define CONNECT_SERVER_ERROR ? ? ? ? ? -7
#define UPLOAD_FILE_ERROR ? ? ? ? ? ? ?-8
#define DOWNLOAD_FILE_ERROR ? ? ? ? ? ?-10

class FileClient : public QObject
{
? ? Q_OBJECT
public:
? ? explicit FileClient(QString ip,quint16 port,QObject *parent = nullptr);
? ? ~FileClient();

public slots:
? ? qint64 filesUpload(QStringList filepath_list);
? ? qint64 fileUpload(QString filepath);

? ? qint64 filesDownload(QStringList filepath_list);
? ? qint64 fileDownload(QString filepath);

protected:
? ? qint64 fileUploadHeader(QString filepath);
? ? qint64 fileUploadPos();
? ? qint64 fileUploadContent();
? ? qint64 fileUploadTail();

? ? qint64 fileDownloadHeader(QString filepath);
? ? qint64 fileDownloadContent();
? ? qint64 fileDownloadTail();

? ? qint64 fileUploadRecvData(qint64 req_id,QMap<QString, QVariant>& recv_data);
? ? bool socketConnect();
? ? void paramInit();
? ? qint64 file_clc_md5(QString &md5_value);

private:
? ? QString m_ip;
? ? quint16 m_port;

? ? qint64 m_file_pos;
? ? qint64 m_payloadSize;
? ? qint64 m_file_total_size;

? ? QFile m_local_file;
? ? QTcpSocket m_socket;
};

#endif // FILECLIENT_H

//fileclient.cpp
#include "fileclient.h"

#include <QDataStream>
#include <QHostAddress>
#include <QFile>
#include <QCryptographicHash>
#include <QVariant>
#include <QFile>
#include <QFileInfo>

FileClient::FileClient(QString ip,quint16 port,QObject *parent) :
? ? QObject(parent),
? ? m_ip(ip),
? ? m_port(port),
? ? m_socket(this)
{

}

FileClient::~FileClient()
{
? ? if(this->m_socket.isOpen())
? ? {
? ? ? ? this->m_socket.close();
? ? }
}

qint64 FileClient::filesUpload(QStringList filepath_list)
{
? ? qint64 status=OK;
? ? foreach (QString filepath, filepath_list)
? ? {
? ? ? ? status=this->fileUpload(filepath);
? ? ? ? if(status!=OK)
? ? ? ? {
? ? ? ? ? ? return status;
? ? ? ? }
? ? }

? ? return status;
}

qint64 FileClient::fileUpload(QString filepath)
{
? ? qint64 status=OK;
? ? this->paramInit();

? ? status=this->fileUploadHeader(filepath);
? ? if(status==FILE_ALREADY_EXISTS_ERROR) //already exist
? ? {
? ? ? ? return OK;
? ? }
? ? else if(status!=OK)
? ? {
? ? ? ? this->m_socket.disconnectFromHost();
? ? ? ? return status;
? ? }

? ? status=this->fileUploadPos();
? ? if(status!=OK)
? ? {
? ? ? ? this->m_socket.disconnectFromHost();
? ? ? ? return status;
? ? }

? ? status=this->fileUploadContent();
? ? if(status!=OK)
? ? {
? ? ? ? this->m_socket.disconnectFromHost();
? ? ? ? return status;
? ? }

? ? status=this->fileUploadTail();
? ? if(status!=OK)
? ? {
? ? ? ? this->m_socket.disconnectFromHost();
? ? ? ? return status;
? ? }

? ? return status;
}

qint64 FileClient::filesDownload(QStringList filepath_list)
{
? ? qint64 status=OK;
? ? foreach (QString filepath, filepath_list)
? ? {
? ? ? ? status=this->fileDownload(filepath);
? ? ? ? if(status!=OK)
? ? ? ? {
? ? ? ? ? ? return status;
? ? ? ? }
? ? }

? ? return status;
}

qint64 FileClient::fileDownload(QString filepath)
{
? ? qint64 status=OK;
? ? this->paramInit();
? ? status=this->fileDownloadHeader(filepath);
? ? if(status==FILE_ALREADY_EXISTS_ERROR) //already exists
? ? {
? ? ? ? return OK;
? ? }
? ? else if(status!=OK)
? ? {
? ? ? ? this->m_socket.disconnectFromHost();
? ? ? ? return status;
? ? }

? ? status=this->fileDownloadContent();
? ? if(status!=OK)
? ? {
? ? ? ? this->m_socket.disconnectFromHost();
? ? ? ? return status;
? ? }

? ? status=this->fileDownloadTail();
? ? if(status!=OK)
? ? {
? ? ? ? this->m_socket.disconnectFromHost();
? ? ? ? return status;
? ? }

? ? return status;
}

qint64 FileClient::fileUploadRecvData(qint64 req_id, QMap<QString, QVariant>& recv_data)
{
? ? if(this->m_socket.waitForReadyRead()==false)
? ? {
? ? ? ? return RECV_DATA_TIMEOUT_ERROR;
? ? }

? ? qint64 recv_rsp_id=OK;
? ? QByteArray inblock=this->m_socket.readAll();
? ? QDataStream rsp_in(&inblock,QIODevice::ReadOnly);
? ? rsp_in>>recv_rsp_id>>recv_data;

? ? if(req_id!=recv_rsp_id)
? ? {
? ? ? ? return RECV_UNKNOW_DATA_ERROR;
? ? }

? ? return qint64(recv_data[QString("reply_status")].toInt());
}

qint64 FileClient::fileUploadHeader(QString filepath)
{
? ? if(this->m_socket.isOpen()==false)
? ? {
? ? ? ? if(this->socketConnect()==false)
? ? ? ? {
? ? ? ? ? ? qDebug()<<"socket connect failed:"<<this->m_socket.errorString()<<endl;
? ? ? ? ? ? return CONNECT_SERVER_ERROR;
? ? ? ? }
? ? }

? ? this->m_local_file.setFileName(filepath);
? ? if(this->m_local_file.open(QIODevice::ReadOnly)==false)
? ? {
? ? ? ? qDebug()<<"read file failed:"<<this->m_local_file.errorString()<<endl;
? ? ? ? return FILE_OPEN_ERROR;
? ? }
? ? this->m_file_total_size=this->m_local_file.size();
? ? this->m_local_file.close();

? ? QByteArray outblock;
? ? QDataStream file_out(&outblock,QIODevice::WriteOnly);
? ? QMap<QString,QVariant> file_header;
? ? file_header[QString("file_prjpath")]=QVariant(filepath.right(filepath.size()-filepath.lastIndexOf('/')-1));
? ? file_out<<qint64(FILE_UPLOAD_HEADER)<<file_header;

? ? this->m_socket.write(outblock);
? ? this->m_socket.waitForBytesWritten();

? ? QMap<QString, QVariant> rsp_msg;
? ? qint64 recv_status=this->fileUploadRecvData(FILE_UPLOAD_HEADER,rsp_msg);
? ? if(recv_status!=OK)
? ? {
? ? ? ? return recv_status;
? ? }
? ? this->m_file_pos=rsp_msg[QString("file_pos")].toInt();
? ? QString recv_md5=rsp_msg[QString("file_md5")].toString();

? ? if(this->m_file_pos==0)
? ? {
? ? ? ? return OK;
? ? }
? ? else
? ? {
? ? ? ? if(this->m_local_file.open(QIODevice::ReadOnly)==false)
? ? ? ? {
? ? ? ? ? ? return FILE_OPEN_ERROR;
? ? ? ? }

? ? ? ? qint64 readtotalBytes=0;
? ? ? ? qint64 payloadSize=10*1024*1024;
? ? ? ? QCryptographicHash clc_md5(QCryptographicHash::Md5);
? ? ? ? while(readtotalBytes<this->m_file_pos)
? ? ? ? {
? ? ? ? ? ? qint64 readBytes=qMin(payloadSize,this->m_file_pos-readtotalBytes);
? ? ? ? ? ? clc_md5.addData(this->m_local_file.read(readBytes));
? ? ? ? ? ? readtotalBytes+=readBytes;
? ? ? ? }
? ? ? ? this->m_local_file.close();

? ? ? ? if(QString(clc_md5.result().toHex())!=recv_md5)
? ? ? ? {
? ? ? ? ? ? this->m_file_pos=0;
? ? ? ? }

? ? ? ? this->m_file_total_size-=this->m_file_pos;
? ? ? ? if(this->m_file_total_size==0)
? ? ? ? {
? ? ? ? ? ? return FILE_ALREADY_EXISTS_ERROR;
? ? ? ? }
? ? ? ? else
? ? ? ? {
? ? ? ? ? ? return OK;
? ? ? ? }

? ? }
}

qint64 FileClient::fileUploadPos()
{
? ? QByteArray outblock;
? ? QDataStream file_out(&outblock,QIODevice::WriteOnly);
? ? QMap<QString,QVariant> file_header;
? ? file_header[QString("file_pos")]=QVariant(this->m_file_pos);
? ? file_header[QString("file_size")]=QVariant(this->m_file_total_size);
? ? file_out<<qint64(FILE_UPLOAD_POS)<<file_header;

? ? this->m_socket.write(outblock);
? ? this->m_socket.waitForBytesWritten();

? ? QMap<QString, QVariant> rsp_msg;
? ? qint64 recv_status=this->fileUploadRecvData(FILE_UPLOAD_POS,rsp_msg);

? ? return recv_status;
}

qint64 FileClient::fileUploadContent()
{
? ? if(this->m_socket.isOpen()==false)
? ? {
? ? ? ? return CONNECT_SERVER_ERROR;
? ? }

? ? if(this->m_local_file.open(QIODevice::ReadOnly)==false)
? ? {
? ? ? ? return FILE_OPEN_ERROR;
? ? }
? ? this->m_local_file.seek(this->m_file_pos);

? ? while(this->m_file_total_size!=0)
? ? {
? ? ? ? this->m_file_total_size-=this->m_socket.write(this->m_local_file.read(qMin(this->m_file_total_size,this->m_payloadSize)));
? ? ? ? this->m_socket.waitForBytesWritten();
? ? }

? ? return OK;
}

qint64 FileClient::fileUploadTail()
{
? ? if(this->m_socket.isOpen()==false)
? ? {
? ? ? ? return CONNECT_SERVER_ERROR;
? ? }

? ? QMap<QString, QVariant> rsp_msg;
? ? qint64 recv_status=this->fileUploadRecvData(FILE_UPLOAD_TAIL,rsp_msg);
? ? return recv_status;
}

qint64 FileClient::fileDownloadHeader(QString filepath)
{
? ? if(this->m_socket.isOpen()==false)
? ? {
? ? ? ? if(this->socketConnect()==false)
? ? ? ? {
? ? ? ? ? ? qDebug()<<"connect server error"<<endl;
? ? ? ? ? ? return CONNECT_SERVER_ERROR;
? ? ? ? }
? ? }

? ? qint64 file_pos=0;
? ? QString file_md5_value;
? ? this->m_local_file.setFileName(filepath);
? ? if(this->m_local_file.open(QIODevice::ReadOnly)==false)
? ? {
? ? ? ? file_pos=0;
? ? }
? ? else
? ? {
? ? ? ? file_pos=this->m_local_file.size();
? ? ? ? qint64 readtotalBytes=0;
? ? ? ? qint64 payloadSize=10*1024*1024;
? ? ? ? QCryptographicHash clc_md5(QCryptographicHash::Md5);
? ? ? ? while(readtotalBytes<file_pos)
? ? ? ? {
? ? ? ? ? ? qint64 readBytes=qMin(payloadSize,file_pos-readtotalBytes);
? ? ? ? ? ? clc_md5.addData(this->m_local_file.read(readBytes));
? ? ? ? ? ? readtotalBytes+=readBytes;
? ? ? ? }
? ? ? ? file_md5_value=QString(clc_md5.result().toHex());
? ? ? ? this->m_local_file.close();
? ? }

? ? QByteArray outblock;
? ? QDataStream file_out(&outblock,QIODevice::WriteOnly);
? ? QMap<QString,QVariant> file_header;
? ? file_header[QString("file_prjpath")]=QVariant(filepath);
? ? file_header[QString("file_pos")]=QVariant(file_pos);
? ? file_header[QString("file_md5")]=QVariant(file_md5_value);
? ? file_out<<qint64(FILE_DOWNLOAD_HEADER)<<file_header;

? ? this->m_socket.write(outblock);
? ? this->m_socket.waitForBytesWritten();

? ? QMap<QString, QVariant> rsp_msg;
? ? qint64 recv_status=this->fileUploadRecvData(FILE_DOWNLOAD_HEADER,rsp_msg);
? ? if(recv_status!=OK)
? ? {
? ? ? ? return recv_status;
? ? }

? ? this->m_file_pos=rsp_msg[QString("file_pos")].toInt();
? ? this->m_file_total_size=rsp_msg[QString("file_size")].toInt();

? ? if(0==this->m_file_total_size)
? ? {
? ? ? ? qDebug()<<"file already exist error"<<endl;
? ? ? ? return FILE_ALREADY_EXISTS_ERROR;
? ? }

? ? QByteArray outblock2;
? ? QDataStream file_out2(&outblock2,QIODevice::WriteOnly);
? ? QMap<QString,QVariant> file_header2;
? ? file_header2[QString("reply_status")]=QVariant(qint64(OK));
? ? file_out2<<qint64(FILE_DOWNLOAD_CONTENT)<<file_header2;

? ? this->m_socket.write(outblock2);
? ? this->m_socket.waitForBytesWritten();

? ? return OK;
}

qint64 FileClient::fileDownloadContent()
{?
? ? if(this->m_local_file.open(QIODevice::WriteOnly)==false)
? ? {
? ? ? ? qDebug()<<"file open error:"<<this->m_local_file.fileName()<<endl;
? ? ? ? return FILE_OPEN_ERROR;
? ? }
? ? this->m_local_file.seek(this->m_file_pos);

? ? qint64 status=OK;
? ? while(this->m_file_total_size>0)
? ? {
? ? ? ? if(this->m_socket.waitForReadyRead()==false)
? ? ? ? {
? ? ? ? ? ? status=RECV_DATA_TIMEOUT_ERROR;
? ? ? ? ? ? break;
? ? ? ? }
? ? ? ? QByteArray inblock=this->m_socket.readAll();
? ? ? ? this->m_file_total_size-=inblock.size();
? ? ? ? if(status==OK)
? ? ? ? {
? ? ? ? ? ? if(this->m_local_file.write(inblock)==-1)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? status=FILE_WRITE_ERROR;
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? this->m_local_file.close();

? ? if(status==OK)
? ? {
? ? ? ? QByteArray outblock2;
? ? ? ? QDataStream file_out2(&outblock2,QIODevice::WriteOnly);
? ? ? ? QMap<QString,QVariant> file_header2;
? ? ? ? file_header2[QString("reply_status")]=QVariant(qint64(OK));
? ? ? ? file_out2<<qint64(FILE_DOWNLOAD_TAIL)<<file_header2;

? ? ? ? this->m_socket.write(outblock2);
? ? ? ? this->m_socket.waitForBytesWritten();
? ? }

? ? return status;
}

qint64 FileClient::fileDownloadTail()
{
? ? QMap<QString, QVariant> rsp_msg;
? ? qint64 recv_status=this->fileUploadRecvData(FILE_DOWNLOAD_TAIL,rsp_msg);

? ? return recv_status;
}

bool FileClient::socketConnect()
{
? ? this->m_socket.close();

? ? this->m_socket.connectToHost(QHostAddress(this->m_ip),this->m_port);
? ? if(this->m_socket.waitForConnected()==false)
? ? {
? ? ? ? qDebug()<<"connect timeout:"<<this->m_ip<<this->m_port<<endl;
? ? ? ? return false;
? ? }

? ? return true;
}

void FileClient::paramInit()
{
? ? this->m_file_pos=0;
? ? this->m_payloadSize=1*1024*1024;//1MB
? ? this->m_local_file.close();
? ? this->m_file_total_size=0;
}

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

相關文章

  • QT實現(xiàn)TCP客戶端自動連接

    QT實現(xiàn)TCP客戶端自動連接

    這篇文章主要為大家詳細介紹了QT中一個TCP客戶端自動連接的測試模型,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2024-12-12
  • QT網絡編程UDP下C/S架構廣播通信(實例講解)

    QT網絡編程UDP下C/S架構廣播通信(實例講解)

    下面小編就為大家?guī)硪黄猀T網絡編程UDP下C/S架構廣播通信(實例講解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-07-07
  • 深入了解c++11 移動語義與右值引用

    深入了解c++11 移動語義與右值引用

    這篇文章主要介紹了c++ 移動語義與右值引用的相關資料,幫助大家更好的理解和學習c++,感興趣的朋友可以了解下
    2020-08-08
  • C++空類詳解

    C++空類詳解

    以下是對C++中的空類進行了詳細的介紹,需要的朋友可以過來參考下
    2013-09-09
  • C語言的線性表之順序表你了解嗎

    C語言的線性表之順序表你了解嗎

    這篇文章主要為大家詳細介紹了C語言的線性表之順序表,線性表的順序表示指的是用一組地址連續(xù)的存儲單元依次存儲線性表中的數(shù)據(jù)元素,本文具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • C語言編程中常見的五種錯誤及對應解決方案

    C語言編程中常見的五種錯誤及對應解決方案

    這篇文章主要給大家分享的是C語言編程中常見的五種錯誤及對應解決方案,詳細內容就請跟小編一起進入下面的文章內容吧
    2021-10-10
  • OpenCV識別圖像上的線條軌跡

    OpenCV識別圖像上的線條軌跡

    這篇文章主要為大家詳細介紹了OpenCV識別圖像上的線條軌跡,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • C++單例模式應用實例

    C++單例模式應用實例

    這篇文章主要介紹了C++單例模式應用實例,詳細講述了單例模式的原理與結構,及相關的打印機應用實例,需要的朋友可以參考下
    2014-10-10
  • 深入講解Socket原理

    深入講解Socket原理

    這篇文章深入的講解Socket原理,并附帶實例代碼。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2021-12-12
  • C++學習之IO流(輸入輸出流)詳解

    C++學習之IO流(輸入輸出流)詳解

    流是一種抽象概念,它代表了數(shù)據(jù)的無結構化傳遞。而用來進行輸入輸出操作的流就稱為IO流。這篇文章主要為大家介紹了C++中IO流的使用詳解,需要的朋友可以參考一下
    2021-12-12

最新評論

谷城县| 从化市| 云南省| 屏东市| 建阳市| 施甸县| 舒城县| 大悟县| 宁明县| 阳泉市| 阳谷县| 东城区| 盐山县| 偏关县| 抚顺市| 方正县| 太湖县| 沂水县| 大渡口区| 额敏县| 乌鲁木齐市| 普兰店市| 扶余县| 榆社县| 施甸县| 沾益县| 青阳县| 同江市| 屏边| 怀来县| 专栏| 峨眉山市| 安阳市| 商城县| 无极县| 水富县| 海伦市| 遵义市| 凉城县| 澄迈县| 鄯善县|