1

おはようございます。QTcpSocketを使用してあるPCから別のPCにファイルを送信する例を探しています。自分でコードを作ってみました。ユーザーが自分のDD(すべてのタイプ)からファイルを選択してTcpServerに送信し、このサーバーがこのファイルを他のクライアントに送信するアプリケーションがありますが、選択すると問題が発生しますファイルと私はそれを送信します。クライアント側では、次のメッセージが表示されます。ファイルは送信中ですが、サーバー側では、ファイルが合計バイト数で受信されていないことを示しています。任意の提案をお願いします。これは、クライアント側でファイルを送信するための関数です。

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);
}

およびサーバー側:

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);
    }

}

そのため、サーバーが受信したファイルを新しいファイルに書き込むことができません。何か提案をお願いします!! よろしくお願いします

4

1 に答える 1

0

あなたのコードは相手を待っていますが、相手はあなたを待っています。双方がお互いを待つことを可能にするプロトコルは、根本的に壊れています。

TCP では、送信者が受信者を待つことはできますが、受信者が送信者を待つことはできません。送信者が受信者を待機できないようにするには、無制限の量のバッファリングが必要になるため、これは理にかなっています。したがって、TCP の上層にあるアプリケーションの場合、受信者は送信者を待たないことがあります。

しかし、あなたは行います:

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

            return;
        }

ここでは、受信する (ソケットからデータをプルする) 前に、送信者が進行する (bytesAvailable が増加する) のを待っています。しかし、送信者は、さらにデータを送信する前に、あなたが進歩するのを待っています。これにより、デッドロックが発生します。これをしないでください。

いつでも、できるだけ早く、できるだけ多くのデータを受信します。すでに受信したデータをネットワーク スタックからプルする前に、ネットワーク経由でさらにデータを受信することを主張しないでください。

于 2012-09-29T08:38:43.030 に答える