Приветствую всех :-)
Передаю по сети файлы, используя QTcpSocket и многопоточность. Соответственно, файл перед отправкой надо разбить на кусочки, на получателе - собрать.
Нашёл тему - http://www.prog.org.ru/topic_10870_0.html (http://www.prog.org.ru/topic_10870_0.html), где уже есть прекрасные готовые куски.
Для разбивки использовал код от 
BRE (спасибо :-), что на второй странице; для сборки - код от 
TukiNov (тоже спасибо :-)
В итоге, у меня это выглядит так:
Разборка и отправка:void threadClient::run()
{
    //qDebug () << "threadClient::run()";
    QTcpSocket tcpSocket;
    if (!tcpSocket.setSocketDescriptor(socketDescriptor)) {
        //qDebug () << "error(tcpSocket.error())";
        return;
    }
    tcpSocket.waitForConnected();
    QByteArray block;
    
    QFile file(filePath);
    QDataStream read(&file);
    file.open(QFile::ReadOnly);
    //отправка служебной информации
    QByteArray bArray;
    QDataStream dStream(&bArray, QIODevice::WriteOnly);
    dStream.setVersion(QDataStream::Qt_4_5);
    dStream << quint64(file.size());
    dStream << CRC32(filePath);
    //qDebug () << "CRC sended: " << CRC32(filePath);
    dStream << filePath;
    dStream << inPath;
    tcpSocket.write(bArray);
    tcpSocket.flush();
   
    ong int lBytes = 0;
    char ch [1024];
    ch[1023] = '\0';
    int i=0;
    while(!read.atEnd()){
      int l = read.readRawData(ch, sizeof(char)*1023);
      QByteArray ba(ch, sizeof(char)*l);
      lBytes += tcpSocket.write(ba, sizeof(char)*l);
      
//!!Вот этот qDebug
      qDebug () << "block.size: " << i;
      i++;
//!!
      tcpSocket.flush();
      if (-1 == lBytes){
        qWarning() << "Error";
        tcpSocket.close();
        return;
      }
      float procentage = ((float)lBytes / file.size()) * 100;
      emit setProcentage((int)procentage);
    }//while(!readEnd())
    free((void*)ch);
void FortuneThread::run()
{
    qDebug () << "FortuneThread::run()";
    QTcpSocket tcpSocket;
    if (!tcpSocket.setSocketDescriptor(socketDescriptor)) {
        emit error(tcpSocket.error());
        return;
    }
    quint64 fileSize;
    quint32 CRCgeted;
    QString getedFilePath;
    QString usedFilePath;
    tcpSocket.waitForReadyRead(-1);
    QByteArray bArray;
    QDataStream dStream(&bArray, QIODevice::ReadWrite);
    dStream.setVersion(QDataStream::Qt_4_5);
    bArray = tcpSocket.readAll();
    dStream >> fileSize;
    qDebug () << "fileSize" << fileSize;
    dStream >> CRCgeted;
    qDebug () << "CRCgeted" << CRCgeted;
    dStream >> getedFilePath;
    qDebug () << "getedFilePath" << getedFilePath;
    dStream >> usedFilePath;
    qDebug () << "usedFilePath" << usedFilePath;
    //Приём и сборка файла
    QFile save(usedFilePath);
    save.open(QFile::WriteOnly);
    QDataStream write(&save);
    write.setVersion(QDataStream::Qt_4_5);
    long int lBytesDone = 0; //Пока ничего не приняли
    long int lSize = fileSize;
    qDebug () << "lSize" << lSize;
    long int lBytes;
    while (lBytesDone < lSize){//Пока приняли меньше, чем указано
        //Ожидаем данные
        //qDebug () << "In while";
        lBytes = 0;
        while (lBytes == 0) lBytes = tcpSocket.waitForReadyRead(-1);
        //qDebug () << "tcpSocket readyread";
        if (-1 == lBytes){//Если произошла ошибка сокета, то
            qWarning("-----TFileServer: Aborting download.");
            //qDebug () << "EROOR!!";
            tcpSocket.close();
            return;
        }//if (-1 == lBytes)
        QByteArray tmp = tcpSocket.readAll();
        lBytes += write.writeRawData(tmp.data(), tmp.size());
        //qDebug () << "lBytes: " << lBytes;
        lBytesDone += tmp.size();
        //qDebug () << "lBytesDone" << lBytesDone;
        float procentage = ((float)lBytes / fileSize) * 100;
        //qDebug () << "procentage" << procentage;
        //emit setProcentage((int)procentage);
        }//while (lBytesDone < lSize)
    save.close();
    qDebug () << "File saved";
    exec();
}
На маленьких файлах (до мегабайта) всё работает прекрасно. При попытке передать файл в мегабайт - файл записан не полностью.
Тогда я вставил строчки:
qDebug () << "block.size: " << i;
i++;
Просто для того, чтобы проверить, всё ли записывается на отправителе.
И оно заработало.
Если закомментить qDebug - не работает. Если просто выводить "blockSize" без i - не работает.
Если оставить - всё прекрасно передаётся (пробовал на файлах в 700 мегов включительно).
Объяснить это кроме как It's magic! я не могу. разве что, qDebug даёт какую-то минимальную задержку, которая нужна tcpSocket'у для write перед flush...
Так что, оно, конечно, сейчас работает, но является, несомненно, невероятным костылём.
Не подскажете ли, в чём именно дело (ну оооочень интересно) и как костыль убрать.
Заранее спасибо :-)
Делай bool QAbstractSocket::waitForBytesWritten ( int msecs = 30000 ) [virtual] в передатчике.
					Да. А  flush можешь убрать, он тут не нужен.