qt6 c++ 发送大于64K的文件,使用分块传输的方式

栏目:日记 作者:rice 发表时间:2025-08-31 03:13:01阅读:12次

qt6 c++ 发送大于64K的文件,使用分块传输的方式

通过网络发送文件时,遇到发送的文件大于64K,但只能接收到64K的文件的问题。

在网上搜索:qt6 c++ 发送大于64K的文件

搜到百度AI的一篇文章,该文章使用循环多次发送的方法发送大于64K的文件。

该文章的可用性还没有验证。

百度AI原文:

qt6 c++ 客户端通过网络接收发送大于64K的文件

在Qt 6中使用C++编写客户端程序来通过网络接收和发送大于64KB的文件,通常涉及到TCP/IP协议的使用。Qt提供了QTcpSocket类用于实现TCP客户端的功能。为了处理大文件传输,你可以使用分块传输(chunked transfer)的方式,这意味着将大文件分割成多个小块进行发送和接收。

下面是如何使用QTcpSocket来实现这个功能的一个基本示例:
1. 发送大文件

首先,你需要定义一个函数来分割文件并发送每一块数据。

#include <QTcpSocket>
#include <QFile>
#include <QDataStream>
 
void sendFile(QTcpSocket *socket, const QString &filePath) {
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly)) {
        qDebug() << "Failed to open file for reading";
        return;
    }
 
    QByteArray buffer;
    const qint64 chunkSize = 64 * 1024; // 64KB per chunk
    while (!file.atEnd()) {
        buffer = file.read(chunkSize);
        QDataStream out(&buffer, QIODevice::WriteOnly);
        out.setVersion(QDataStream::Qt_5_15); // Ensure compatibility
        out << static_cast<quint64>(buffer.size()); // Write the size of the chunk before sending data
        socket->write(buffer);
        socket->waitForBytesWritten(); // Wait for the data to be sent (or use signals/slots)
    }
    buffer.clear(); // EOF marker
    QDataStream endStream(&buffer, QIODevice::WriteOnly);
    endStream << static_cast<quint64>(0); // Send a 0-sized chunk to indicate EOF
    socket->write(buffer);
    socket->waitForBytesWritten(); // Wait for the EOF marker to be sent (or use signals/slots)
    file.close();
}

2. 接收大文件

然后,你需要定义一个函数来接收这些分块数据并重新组合成原始文件。

#include <QTcpSocket>
#include <QFile>
#include <QDataStream>
 
void receiveFile(QTcpSocket *socket, const QString &savePath) {
    QFile file(savePath);
    if (!file.open(QIODevice::WriteOnly)) {
        qDebug() << "Failed to open file for writing";
        return;
    }
    QDataStream in(socket);
    in.setVersion(QDataStream::Qt_5_15); // Ensure compatibility
    quint64 size;
    forever {
        in >> size; // Read the size of the incoming chunk
        if (size == 0) break; // Break if we reach the EOF marker
        char *data = new char[size];
        in.readRawData(data, size); // Read the chunk data
        file.write(data, size); // Write the chunk to the file
        delete[] data; // Clean up allocated memory
    }
    file.close();
}

3. 使用信号和槽处理异步IO(推荐方式)

为了避免阻塞UI线程,你应该使用信号和槽机制来处理数据的读写。例如:

connect(socket, &QTcpSocket::readyRead, [=]() {
    receiveFile(socket, "path/to/save/file.ext"); // Assuming you're receiving the file here.
});

对于发送,你可以在文件读取的循环中使用QTcpSocket的write()函数,并通过信号和槽机制处理写入完成:

connect(socket, &QTcpSocket::bytesWritten, [=](qint64 bytes) {
    // Handle bytes written, e.g., move to next chunk or finish sending.
});

4. 注意事项:

    确保服务器端也实现了相应的分块接收逻辑。

    使用waitForBytesWritten()在某些情况下可能会导致性能问题,特别是在UI线程中。考虑使用非阻塞方式(例如,通过信号和槽处理数据传输)。

    处理网络错误和异常情况(如连接断开、数据损坏等)。可以通过连接QTcpSocket的错误信号来实现。例如:connect(socket, &QTcpSocket::errorOccurred, [](QAbstractSocket::SocketError error){ /* handle error */ });。

提示:AI自动生成,仅供参考