2012-09-29 147 views
1

早上好,我正在尋找一個關於用QTcpSocket從一臺電腦發送文件到另一臺電腦的例子。我試圖創建自己的代碼。我有一個應用程序,其中,用戶將從他的DD(所有類型)中選擇一個文件並將其發送到TcpServer,然後該服務器將此文件發送給其他客戶端。但是,我遇到問題,當我選擇該文件,我發送它,在客戶端,我有這樣的信息:文件正在發送,但在服務器端,它表明,該文件沒有收到它的totaly字節。 請任何建議。這是在客戶端的端發送的文件中的函數:QTcp [服務器和套接字]:無法讀取文件發送

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

} 

所以我不能寫服務器收到到一個新的文件的文件。 請任何建議!並提前致謝

回答

0

您的代碼正在等待另一方,但另一方正在等待你。任何允許雙方等待對方的協議基本上已經被打破。

TCP允許發送方等待接收方,但不允許接收方等待發送方。這是有道理的,因爲不允許發送者等待接收者需要無限次的緩衝。因此,對於TCP上分層的任何應用程序,接收者可能不會等待發送者。

但你這樣做:

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

      return; 
     } 

在這裏,你正在等待發送者取得進展(bytesAvailable以增加),你願意接受(從插槽中拔出數據)前。但發件人正在等待您在願意發送更多數據之前取得進展。這會導致死鎖。不要這樣做。

儘可能多地儘可能地接收儘可能多的數據。 千萬不要堅持通過網絡接收更多數據,然後才能從網絡堆棧中提取已收到的數據。

+0

感謝您的回覆。你的意思是我必須從我的代碼中刪除這部分!但是當我這樣做,我的服務器應用程序崩潰,也沒有收到數據 – tasnim

+0

@tasnim:是的,這是第一步。它是有道理的,一旦你修復一個bug,一個新的bug顯示它的臉。你必須繼續下去,直到你修復了所有的錯誤。 –

+0

如何寫我的文件只是在客戶端。我的意思是,當我從客戶端接收文件時,服務器將直接發送給其他客戶端,這將寫入文件,可能是問題是在寫入文件中的服務器端!!這將解決我的問題! – tasnim