Russian Qt Forum

Qt => Работа с сетью => Тема начата: MarTrener от Февраль 11, 2016, 09:58



Название: TCP, проблема передачи больших файлов.
Отправлено: MarTrener от Февраль 11, 2016, 09:58
Добрый день!
Помогите разобраться, почему в моем коде иногда пакеты и файлы 60+ мб доходят, а иногда и 20 мб падает почти сразу..
Я понимаю, что передач полно, бери любую, но все таки..

Клиент:
Код:
QByteArray  arrBlock;
    qint64 fileSize;
    QDataStream out(&arrBlock, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_5_0);

    sendFile = new QFile(filePatch);
    sendFile->open(QFile::ReadOnly);

    QFileInfo fi(filePatch);
    QString fileName = fi.fileName();
    fileSize = fi.size();

    QByteArray buffer = sendFile->readAll();

    out << quint16(0) << QTime::currentTime() << QString("FILE")
            << fileName << fileSize << buffer;

    out.device()->seek(0);
    out << quint16(arrBlock.size() - sizeof(quint16));

    tcpSocket->write(arrBlock);

И принимающая сторона.

Код:
void Server::ReadMessage()
{
    QTime   time;
    QString type;

    QTcpSocket *client = (QTcpSocket*)(sender());
    QDataStream in(client);
    in.setVersion(QDataStream::Qt_5_0);

    qDebug() << client->bytesAvailable();
    if (!nextBlockSize) {
        if (quint16(client->bytesAvailable()) < sizeof(quint16)) {
            return;
        }
        in >> nextBlockSize;
    }

    if (client->bytesAvailable() < nextBlockSize) {
        return;
    }
    in >> time >> type;
...
SendingFile(client);

}

void Server::SendingFile(QTcpSocket *client)
{
    QTcpSocket* mClientSocket = (QTcpSocket*)sender();
    QDataStream in(client);
    in.setVersion(QDataStream::Qt_5_0;

    QByteArray buffer;
    QString fileName;
    qint64 fileSize;

    in >> fileName >> fileSize;
    qDebug() << fileName;
    qDebug() << fileSize;

        forever
        {
            if (!nextBlockSize) {

                if (quint16(client->bytesAvailable()) < sizeof(quint16)) {
                    break;
                }
                in >> nextBlockSize;
            }

            in >> buffer;

            if (client->bytesAvailable() < nextBlockSize) {
                break;
            }
        }

        QFile receiveFile(dirDownloads + fileName);
        receiveFile.open(QIODevice::ReadWrite);
        receiveFile.write(buffer);
        receiveFile.close();
        buffer.clear();
    nextBlockSize = 0;
}
   

Я думаю, что дело в quint16, но не знаю, лучше послушаю Вас  :)


Название: Re: TCP, проблема передачи больших файлов.
Отправлено: neckt0 от Февраль 11, 2016, 12:04
quint16 виноват


Название: Re: TCP, проблема передачи больших файлов.
Отправлено: MarTrener от Февраль 11, 2016, 12:25
А вот так можно делать?
Текст и заголовок передавать в 16, а сам файл уже в 32 например?
Код:
out << quint16(0) << QTime::currentTime() << QString("FILE")
            << fileName << fileSize << (quint32)buffer;

    out.device()->seek(0);
    out << quint32(arrBlock.size() - sizeof(quint32));

Только как быть потом, на стороне сервера, он в 16 принимает
Код:
if (!nextBlockSize) {
        if (quint16(client->bytesAvailable()) < sizeof(quint16)) {
            return;
        }
        in >> nextBlockSize;
    }

    if (client->bytesAvailable() < nextBlockSize) {
        return;
    }



Название: Re: TCP, проблема передачи больших файлов.
Отправлено: qate от Февраль 11, 2016, 12:36
клади сначала размер qint32 (или qint64 если файлы будут более 2гб) и далее сколько надо данных
внутри данных можно делать какие угодно структуры со своими заголовками и данными



Название: Re: TCP, проблема передачи больших файлов.
Отправлено: MarTrener от Февраль 11, 2016, 12:49
Спасибо, я уже менял 16 на 32, но думал проблема в другом.. Сейчас в нужных местах аккуратно все исправил, и наконец-то все пошло поехало :)
Благодарю!  ;)

И раз получилось оформить передачу, заодно спрошу, можно ли узнать скорость записи как-то? Это к вопросу о ProgressBar, слежение за отправленным файлом..


Название: Re: TCP, проблема передачи больших файлов.
Отправлено: qate от Февраль 12, 2016, 12:56
можно ли узнать скорость записи как-то? Это к вопросу о ProgressBar, слежение за отправленным файлом..

Разбивай файл на части (как сам решишь) и отправляй по частям
Например 100Мб файл отправляй по 1Мб