1

Good morning, I’m looking for an example about sending a file from one pc to an other with QTcpSocket. I tried to create my own code. I have an application, in which, the user will choose a file from his DD ( all types) and send it to the TcpServer, this server will then send this file to the other clients.But, I have a problem, when i choose the file and i send it, in the client’s side, i have this message: file is sending , but in the server’s side, it shows me that the file isn’t recieved with it’s totaly bytes. Any suggestion please. This is the function for sending the file in the client’s side:

void FenClient::on_boutonEnvoyer_2_clicked()
{
    QString nomFichier = lineEdit->text();
        QFile file(lineEdit->text());
        if(!file.open(QIODevice::ReadOnly))
        {
            qDebug() << "Error, file can't be opened successfully !";
            return;

        }

        QByteArray bytes = file.readAll();

        QByteArray block;
        QDataStream out(&block, QIODevice::WriteOnly);

        out << quint32(0);
        out << nomFichier;
        out << bytes;
        out.device()->seek(0);
        out << quint32((block.size() - sizeof(quint32)));

        qDebug() << "Etat : envoi en cours...";
         listeMessages->append("status : sending the file...");

        socket->write(block);
}

and the server side:

void FenServeur::datarecieved()
{

    QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());

        if(socket == 0)
        {
            qDebug() << "no Socket!";
            return;
        }

        forever
        {
            QDataStream in(socket);
            if(blockSize == 0)
            {
                if(socket->bytesAvailable()  )
                {
                    qDebug() << "Error < sizeof(quint32))";
                    return;
                }

                in >> blockSize;
            }

            if(socket->bytesAvailable() < blockSize)
             {
                qDebug() << "data not recieved with its total bytes";

                return;
             }

            qDebug() << "!!!!!!";
            QByteArray dataOut;
            QString nameFile;
            in >> nameFile >> dataOut;
            QFile fileOut(nameFile);
            fileOut.open(QIODevice::WriteOnly);
            fileOut.write(dataOut);
            fileOut.close();

            blockSize = 0;
         }
}

void FenServeur::sendToAll(const QString &message)
{

    QByteArray paquet;
    QDataStream out(&paquet, QIODevice::WriteOnly);

    out << (quint32) 0;
    out << message;
    out.device()->seek(0);
    out << (quint32) (paquet.size() - sizeof(quint32));
    for (int i = 0; i < clients.size(); i++)
    {
        clients[i]->write(paquet);
    }

}

So i can't write the file that the server recieved into a new file. Any suggestion please!! and thanks in advance

tasnim
  • 11
  • 1

1 Answers1

0

Your code is waiting for the other side, but the other side is waiting for you. Any protocol that allows both sides to wait for each other is fundamentally broken.

TCP allows the sender to wait for the receiver but does not allow the receiver to wait for the sender. This makes sense because not allowing the sender to wait for the receiver requires an unlimited amount of buffering. Thus for any application layered on top of TCP, the receiver may not wait for the sender.

But you do:

        if(socket->bytesAvailable() < blockSize)
        {
            qDebug() << "data not recieved with its total bytes";

            return;
        }

Here, you are waiting for the sender to make progress (bytesAvailable to increase) before you are willing to receive (pull data from the socket). But the sender is waiting for you to make progress before it is willing to send more data. This causes a deadlock. Don't do this.

Receive as much data as you can, as soon as you can, whenever you can. Never insist on receiving more data over the network before you will pull already received data from the network stack.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • Thanks for your reply. You mean that i have to delete this part from my code!! but when i do this, my server application crashes and no data recieved also – tasnim Sep 29 '12 at 09:40
  • @tasnim: Yes, that's the first step. It makes sense that once you fix one bug, a new bug shows it face. You have to keep going until you've fixed all the bugs. – David Schwartz Sep 29 '12 at 11:57
  • what about writing my file just in the client side.I mean, when i recieve the file from the client, the server will directly send it toother clients, which will write it into files, may be the problem is in writing file in the server side!! will this solve my problem!!! – tasnim Sep 29 '12 at 15:19