Qt文件传输模块(全)

简述

此文章记录了,Qt的Tcp文件传输功能,实现了文件的上传下载等,记录源码使用教程等。(仅自用!)

目录

    • 简述
    • 功能介绍
      • 1.文件的上传和下载
      • 2.文件的MD5校验
      • 3.多文件同时传输机制
        • 介绍
        • 文件分配流程
      • 4.传输速度控制
      • 5.传输异常处理
      • 6.网络恢复重传
      • 7.断点续传
      • 8.传输加密
      • 9.代码

功能介绍

  1. 文件和文件夹的上传与下载
  2. 文件MD5的校验
  3. 多文件传输机制
  4. 传输速度控制
  5. 传输异常处理
  6. 网络恢复重传
  7. 断点续传
  8. 传输加密
  9. 代码

1.文件的上传和下载

简单的画了两个流程图以表逻辑清晰。

①上传流程图
Qt文件传输模块(全)_第1张图片

②下载流程图
Qt文件传输模块(全)_第2张图片

2.文件的MD5校验

①文件的MD5校验是文件的开始与完成的时候进行校验,开始校验如果相同就直接发送结束。完成时校验是判断文件的完整性。
②获取MD5函数
//千万不要使用readAll否则大文件会溢出
此函数加入pos主要是断点续传进行文件前的MD5校验。

/*获取绝对路径MD5*/
static const QString countMd5(const QString filePath, qint64 pos = 0);

const QString FileTransfer::countMd5(const QString filePath, qint64 pos)
{
    QFile localFile(filePath);
    if (!localFile.open(QFile::ReadOnly))
    {
        qDebug() << "file open error." << localFile.errorString();
        return 0;
    }
    QCryptographicHash ch(QCryptographicHash::Md5);

    //文件总大小
    quint64 totalBytes = 0;
    //已读取的文件大小
    quint64 bytesWritten = 0;
    //等待读取的文件大小
    quint64 bytesToWrite = 0;
    //每次读取的文件大小
    quint64 loadSize = 1024 * 4;

    QByteArray buf;

    //获取文件大小
    if (pos != 0) {
        totalBytes = pos;
    }
    else {
        totalBytes = localFile.size();
    }
    bytesToWrite = totalBytes;

    //循环读取文件
    while (1)
    {
        if(bytesToWrite > 0)
        {
            buf = localFile.read(qMin(bytesToWrite, loadSize));
            ch.addData(buf);
            bytesWritten += buf.length();
            bytesToWrite -= buf.length();
            buf.resize(0);
        }
        else
        {
            break;
        }

        if(bytesWritten == totalBytes)
        {
            break;
        }
    }

    //关闭文件
    localFile.close();

    return ch.result().toHex();
}

3.多文件同时传输机制

介绍

多文件同时传输,采用的是有客户端创建一个文件传输的管理类,通过管理类来创建出多个文件传输类进行文件的同时传输。

同时由管理类来管理子线程的分发机制。

文件分配流程

①通过管理类对文件的上传或下载数量进行new出相应的文件传输线程(可自由设置数量)。
②文件传输类创建后会初始化Socket链接服务器,当与服务器链接成功会通知文件传输管理类。
③当文件管理类收到连接成功的通知,会开始对该线程进行文件分配开始上传。
④当文件上传成功后,会通知管理类,管理类继续获取下一个文件,继续分配给当前线程,以此循环,直至全部完成线程销毁。

4.传输速度控制

上面介绍的文件传输管理类是一个单任务多文件传输机制,如果在客户端中设置了全局的上传速度,那么需要考虑的是多任务多文件传输。
例如:

我客户端设置了上传限制1m/s,我新建了一个上传任务A,里面有5个文件,那么这五个文件的速度应该保持200kb左右。然后我又创建了任务B,有5个文件,那么我如果之修改任务B的传输速度的话,那么整体的传输速度会超过1m。

所以在创建任务B的时候需要通知任务A,将其在传输中的线程块大小/2,依此类推来保持1m传输速度。只有这样才能保重多任务多文件传输控制速度。

注:代码中只实现了上传速度的控制。

下载速度控制问题总结:
需要考虑的本地和服务器带宽,服务器带宽分配问题,如果控制服务器带宽不跑满?如何给用户分配固定的带宽?等问题.

5.传输异常处理

文件传输过程中异常情况很多可能,例如:文件传输中文件丢失,服务器写入文件失败,传输结束时文件丢失,偶遇同文件传输,权限问题,文件打开失败,等等很多,代码中并没有全部完善,需要一点点的调试积累才可以让程序更加的屹立不倒。

6.网络恢复重传

这里贴一段小代码,用来监听网络的状态。发送给文件传输管理类,如果网络恢复管理类再去调用子线程开始传输即可。

while (1) {
        msleep(2000);
        QProcess pro;
        qint32 value = pro.execute("ping baidu.com -n 1");
        if (value == 1 && flag) {
            qDebug() << "网络断开";
            emit signalNetWork(false);
            flag = false;
        }
        //只有断网后来网才发送网络回复
        if (value == 0 && !flag) {
            qDebug() << "网络恢复";
            emit signalNetWork(true);
            flag = true;
        }
    }

7.断点续传

断点续传例如上传:服务器判断文件是否存在后在判断MD5是否匹配,不匹配就可能是续传,需要吧当前文件的MD5计算一下发送给客户端,客户端收到后,从服务器发送的位置读取本地文件进行校验服务器发来的MD5是否相等,如果相等那就从当前位置开始传输如果不相等应特殊处理。
Qt文件传输模块(全)_第3张图片

8.传输加密

传输加密采用AES,加密方式可自行选择,这里不介绍加密代码。
加密解密都是在封包与拆包这里进行操作。只介绍一下如何通知加解密。

在这里插入图片描述
①在拆包封包处加上了key参数,如果key不为空那么就加密或者解密。
②所以我们在上传开始的时候增加新枚举作为标记,服务端收到就进行标记。
③加密下载也相同,通知服务端加密开始即可.
④下面是加解密的地方,如果是加密就吧包拼好后在加密,如果是解密先解密在拆包。建议采用AES_CTR模式。
在这里插入图片描述

9.代码

这里没有做demo示例,因为做了也未必符合你想要的需求,上面记录了自己的一些思路,模块代码中注释很多不乱,没有什么较难的代码思路清晰就行。

还有很多机制bug等,慢慢完善。

项目地址
https://gitee.com/xiaoxin5210/qtcp-module

你可能感兴趣的:(Qt-功能分享,qt)