2012-09-29 2 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 : 예, 그 첫 단계입니다. 하나의 버그를 고치면 새로운 버그로 인해 그 사실을 알 수 있습니다. 모든 버그를 고칠 때까지 계속 가야합니다. –

+0

클라이언트 측에서 내 파일을 작성하는 것은 어떻습니까? 내 말은, 클라이언트에서 파일을 수신하면 서버가 직접 다른 클라이언트에 파일을 보냅니다. 그러면 클라이언트가 파일을 쓰고 문제가있을 수 있습니다. 서버 측!! 이게 내 문제를 해결할 것인가? – tasnim

관련 문제