QT实现TCP断点传输文件

网上这方面的资源不是很多,大多数都是Http的断点续传。因小项目需求需要做一个断点传输的功能,思考后自己设计了。

服务器和客户端都基于QT5.9,在这里只给出服务器传输文件到客户端,客户端上传文件到服务器原理一样。

原理如下:

  • 将文件分块传输,比如每次发送4096字节。
  • 保证客户端正确接收字节且写入文件,然后向服务器反馈接收成功信息。
  • 服务器收到反馈信息继续进行发送。
  • 暂停下载后记录断点,欲再次下载则发送断点等数据到服务器。
  • 服务器收到断点后,根据断点将文件指针移动到断点位置继续发送。

在这里只给出部分代码,全部代码可查看github。

客户端:

头文件


#pragma once
#ifndef DOWNLOADFILE_H_
#define DOWNLOADFILE_H_
#include "stdafx.h
#include <QFile> 
#include <QString> 
#include "FileInfo.h"
//extern TcpClient * tcp;
extern QString ip;
extern int port;
extern QString globalUserName;

//只负责下载就行了
class DownloadFile : public QObject
{
Q_OBJECT

public:
explicit DownloadFile(QString,QString,int);
//这个构造函数是下载断点文件,第一个是总数据,第二个是断点位置
DownloadFile(int,QString,QString, qint64 ,qint64 ,int );
~DownloadFile();
bool insertRecord();
bool updateRecord();

private:
int index; //序号
QTcpSocket *tcpSocket; //连接服务器的socket
QTime downloadTime;
QTimer *timer;
QFile *newFile;
QByteArray inBlock;
QByteArray outBlock; //发数据给服务器
QByteArray buffer; //用来缓存的
QString fileName;
QString saveFileName; //文件路径加文件名
QString filePath;
QString openFileName; //直接打开的文件名

qint64 RtotalSize; //总共需要发送的文件大小(文件内容&文件名信息) 
qint64 byteReceived; //已经接收的大小 ‘’

qint64 receiveStatus = -1; //默认为继续发送

qint64 sumBlock;
qint64 breakPoint;
qint64 cbreakPoint;
qint64 recordId;
int breakFileId;
QString breakFileName;
QString breakFilePath;

qint64 fileId;
int receiveTime;    //接受的次数
double speed;

QString leftTime; //剩余时间
bool isBreakFile = false;
void init();
bool keepOn;
void countLeftTime(float);


private slots:

void receiveFile(); //从服务器下载文件到本地。
void receiveBreakFile();
void updateSpeed();
void stopReceive(int);

signals:
//void sendDisconnect(QString); //这是什么
void downloadOver(int);
void updateProgress(int, qint64, qint64);
void updateSpeedLabel(int, double,QString);

void addToBreakFile(int, qint64 recordId,int fileId,
QString fileName,QString filePath,
qint64 breakPoint);

};
#endif // !DOWNLOADFILE_H_

downlaodFile.cpp

#include "DownloadFile.h"
#include <QFileDialog>
#include <QtWin>
#include "MyMessageBox.h"
#include "Database.h"
DownloadFile::DownloadFile(QString mFileName, QString mFilePath,int num)
{
fileName = mFileName;
filePath = mFilePath; //总文件就是 filePath + fileName;
index = num;
keepOn = false;
init();

qDebug() << "new downloadFile :" <<QThread::currentThreadId()
<< keepOn;
}
//fileId的名字可能和filename不一样
DownloadFile::DownloadFile(int mFileId,QString mFileName,QString mFilePath, qint64 mBreakPoint,qint64 mRecordId, int num)
{
breakFileName = mFileName;
breakFilePath = mFilePath; //总文件就是 filePath + fileName;
breakFileId = mFileId;
cbreakPoint = mBreakPoint;
recordId = mRecordId;
index = num;
keepOn = true;
init();
}

DownloadFile::~DownloadFile()
{
//delete ui;
}


//初始化界面 
void DownloadFile::init()
{
QString bs;
QString data;
tcpSocket = new QTcpSocket(); //新建一个socket
tcpSocket->abort(); //取消已有的连接
tcpSocket->connectToHost(ip, port); //将这个socket连接到服务器
byteReceived = 0;
receiveTime = 0;
if (!keepOn)
{
bs = "downloadFile";
data = bs + "#" + fileName + "#" + globalUserName;
}
else
{

bs = "downloadBreakFile";
//cbreakPoint断点处,因为等于sumblock的值
data = bs + "#" + QString::number(breakFileId) + "#" + QString::number(cbreakPoint) + "#" + globalUserName ;
}

QByteArray datasend = data.toUtf8(); //发送UTF8过去
if (tcpSocket->write(datasend))
{
qDebug() << 
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值