QTcp [服务器和套接字]:无法读取发送的文件

Posted

技术标签:

【中文标题】QTcp [服务器和套接字]:无法读取发送的文件【英文标题】:QTcp[server and socket]: can't read file sent 【发布时间】:2012-09-29 08:30:51 【问题描述】:

早上好,我正在寻找一个关于使用 QTcpSocket 将文件从一台电脑发送到另一台电脑的示例。我试图创建自己的代码。我有一个应用程序,其中,用户将从他的 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);
    


所以我无法将服务器收到的文件写入新文件。 请有任何建议!!并提前感谢

【问题讨论】:

【参考方案1】:

你的代码在等对方,而对方却在等你。任何允许双方互相等待的协议都从根本上被破坏了。

TCP 允许发送方等待接收方,但不允许接收方等待发送方。这是有道理的,因为不允许发送者等待接收者需要无限量的缓冲。因此对于任何建立在 TCP 之上的应用程序,接收者可能不会等待发送者。

但你这样做:

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

            return;
        

在这里,在您愿意接收(从套接字拉数据)之前,您正在等待发送方取得进展(bytesAvailable 增加)。但是发送者在它愿意发送更多数据之前正在等待你取得进展。这会导致死锁。不要这样做。

尽可能快地接收尽可能多的数据。 永远不要在从网络堆栈中提取已经接收到的数据之前坚持通过网络接收更多数据。

【讨论】:

感谢您的回复。你的意思是我必须从我的代码中删除这部分!但是当我这样做时,我的服务器应用程序崩溃并且也没有收到任何数据 @tasnim:是的,这是第一步。这是有道理的,一旦你修复了一个错误,就会出现一个新错误。在修复所有错误之前,您必须继续前进。 在客户端写入我的文件怎么样。我的意思是,当我从客户端收到文件时,服务器会直接将它发送给其他客户端,它将它写入文件,可能是问题是在服务器端写入文件!这能解决我的问题吗!!!

以上是关于QTcp [服务器和套接字]:无法读取发送的文件的主要内容,如果未能解决你的问题,请参考以下文章

使用来自另一个客户端的广播发射从节点服务器发送的数据无法被 c++ 套接字 io 客户端读取

QDataStream 和 QTcpSocket 上的发送和接收结构

为啥写入此套接字会丢弃读取缓冲区(这真的是发生了啥)?

socket_recv():无法从socket [0]读取:操作成功完成

python3套接字发送接收'字节'对象没有属性'读取'

Android HTTPS 客户端不从套接字读取数据