IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau Discussion :

[QTcpServer] Envoi d'un fichier


Sujet :

Réseau

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Avril 2010
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 20
    Par défaut [QTcpServer] Envoi d'un fichier
    Bonsoir,
    j'ai envoyé un fichier à partir de mon application client à un serveur. Mais mon fichier n'est pas reçu en totalité par le serveur.il y'a une chose qui cloche .
    Ceci est ma fenetreClient.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    #include "FenClient.h"    
    #include <QMenuBar>    
    #include <QMessageBox>    
    #include "qfiledialog.h"    
    #include <QDir>    
     
     
    FenClient::FenClient()    
    {    
        setupUi(this);    
     
        socket = new QTcpSocket(this);    
        connect(socket, SIGNAL(readyRead()), this, SLOT(donneesRecues()));    
        connect(socket, SIGNAL(connected()), this, SLOT(connecte()));    
        connect(socket, SIGNAL(disconnected()), this, SLOT(deconnecte()));    
        connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(erreurSocket(QAbstractSocket::SocketError)));    
     
        tailleMessage = 0;    
    }    
     
    // Tentative de connexion au serveur    
    void FenClient::on_boutonConnexion_clicked()    
    {    
        // On annonce sur la fenêtre qu'on est en train de se connecter    
        listeMessages->append(tr("<em>Tentative de connexion en cours...</em>"));    
        boutonConnexion->setEnabled(false);    
     
        socket->abort(); // On désactive les connexions précédentes s'il y en a    
        socket->connectToHost(serveurIP->text(), serveurPort->value()); // On se connecte au serveur demandé    
    }    
     
    // Appuyer sur la touche Entrée a le même effet que cliquer sur le bouton "Envoyer"    
    void FenClient::on_message_returnPressed()    
    {    
        on_boutonEnvoyer_2_clicked();    
    }    
     
    // On a reçu un paquet (ou un sous-paquet)    
    void FenClient::donneesRecues()    
    {    
     
        QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender()); //--> permet de connaitre le client qui envoi les données (son socket)    
     
            if(socket == 0)    
            {    
                qDebug() << "Pas de Socket!";    
                listeMessages->append("Pas de Socket!");    
                return;    
            }    
     
            forever    
            {    
                QDataStream in(socket);    
                if(blockSize == 0)    
                {   
    if(socket->bytesAvailable()< sizeof(quint32  ))   
    {    
                        qDebug() << "Erreur < sizeof(quint32))";    
                        listeMessages->append("Erreur < sizeof(quint32))");    
                        return;    
                    }    
     
                    in >> blockSize;    
                }    
     
                if(socket->bytesAvailable() < blockSize)    
                 {    
                    qDebug() << "données pas arriver en entier";    
                    listeMessages->append("données pas arriver en entier)");    
                    return;    
                 }    
     
                qDebug() << "!!!!!!";    
                QByteArray dataOut;    
                QString nameFile;    
                in >> nameFile >> dataOut;    
     
     
                QFile fileOut(nameFile);    
                fileOut.open(QIODevice::WriteOnly);    
                fileOut.write(dataOut);    
                fileOut.close();    
                listeMessages->append("fichier reçu");    
                blockSize = 0;    
             }    
     
     
    }    
     
    // Ce slot est appelé lorsque la connexion au serveur a réussi    
    void FenClient::connecte()    
    {    
        listeMessages->append(tr("<em>Connexion réussie !</em>"));    
        boutonConnexion->setEnabled(true);    
    }    
     
    // Ce slot est appelé lorsqu'on est déconnecté du serveur    
    void FenClient::deconnecte()    
    {    
        listeMessages->append(tr("<em>Déconnecté du serveur</em>"));    
    }    
     
    // Ce slot est appelé lorsqu'il y a une erreur    
    void FenClient::erreurSocket(QAbstractSocket::SocketError erreur)    
    {    
        switch(erreur) // On affiche un message différent selon l'erreur qu'on nous indique    
        {    
            case QAbstractSocket::HostNotFoundError:    
                listeMessages->append(tr("<em>ERREUR : le serveur n'a pas pu être trouvé. Vérifiez l'IP et le port.</em>"));    
                break;    
            case QAbstractSocket::ConnectionRefusedError:    
                listeMessages->append(tr("<em>ERREUR : le serveur a refusé la connexion. Vérifiez si le programme \"serveur\" a bien été lancé. Vérifiez aussi l'IP et le port.</em>"));    
                break;    
            case QAbstractSocket::RemoteHostClosedError:    
                listeMessages->append(tr("<em>ERREUR : le serveur a coupé la connexion.</em>"));    
                break;    
            default:    
                listeMessages->append(tr("<em>ERREUR : ") + socket->errorString() + tr("</em>"));    
        }    
     
        boutonConnexion->setEnabled(true);    
    }    
     
    void FenClient::on_ouvrir_clicked()    
    {    
        QString fichier = QFileDialog::getOpenFileName(this, "Ouvrir un fichier", QString(), "objet 3D (*.off *.obj *.ply *.smf *.wrl)");    
     
     
                //  QObject* parent = new QObject();    
                  if ( fichier!=""){    
     
     
                  QFileInfo fi(fichier);    
     
                  QString name=fi.fileName();    
                 //  QString Newname="G:/appmemdos/compression/Release/"+name;    
     
                // bool valid  = QFile::copy (fichier,Newname );//copier un fichier    
     
                 lineEdit->setText(fichier);    
     
    }    
    }    
     
    void FenClient::on_boutonEnvoyer_2_clicked()    
    {    
        QString nomFichier = lineEdit->text();    
            QFile file(lineEdit->text());    
            if(!file.open(QIODevice::ReadOnly))    
            {    
                qDebug() << "Erreur Le fichier n'a pas pu être ouvert !";    
                return;    
                listeMessages->append("Erreur Le fichier n'a pas pu être ouvert !");    
            }    
     
            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("Etat : envoi en cours...");    
            socket->write(block);    
    }
    et le serveur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    #include "FenServeur.h"  
     
    FenServeur::FenServeur()  
    {  
        // Création et disposition des widgets de la fenêtre  
        etatServeur = new QLabel;  
        boutonQuitter = new QPushButton(tr("Quitter"));  
        connect(boutonQuitter, SIGNAL(clicked()), qApp, SLOT(quit()));  
     
        QVBoxLayout *layout = new QVBoxLayout;  
        layout->addWidget(etatServeur);  
        layout->addWidget(boutonQuitter);  
        setLayout(layout);  
     
        setWindowTitle(tr("ZeroChat - Serveur"));  
     
        // Gestion du serveur  
        serveur = new QTcpServer(this);  
        if (!serveur->listen(QHostAddress::Any, 50885)) // Démarrage du serveur sur toutes les IP disponibles et sur le port 50585  
        {  
            // Si le serveur n'a pas été démarré correctement  
            etatServeur->setText(tr("Le serveur n'a pas pu être démarré. Raison :<br />") + serveur->errorString());  
        }  
        else  
        {  
            // Si le serveur a été démarré correctement  
            etatServeur->setText(tr("Le serveur a été démarré sur le port <strong>") + QString::number(serveur->serverPort()) + tr("</strong>.<br />Des clients peuvent maintenant se connecter."));  
            connect(serveur, SIGNAL(newConnection()), this, SLOT(nouvelleConnexion()));  
        }  
     
        tailleMessage = 0;  
    }  
     
    void FenServeur::nouvelleConnexion()  
    {  
        envoyerATous(tr("<em>Un nouveau client vient de se connecter</em>"));  
     
        QTcpSocket *nouveauClient = serveur->nextPendingConnection();  
        clients << nouveauClient;  
     
        connect(nouveauClient, SIGNAL(readyRead()), this, SLOT(donneesRecues()));  
        connect(nouveauClient, SIGNAL(disconnected()), this, SLOT(deconnexionClient()));  
    }  
     
    void FenServeur::donneesRecues()  
    {  
     
     
        QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender()); //--> permet de connaitre le client qui envoi les données (son socket)  
     
            if(socket == 0)  
            {  
                qDebug() << "Pas de Socket!";  
                return;  
            }  
     
            forever  
            {  
                QDataStream in(socket);  
                if(blockSize == 0)  
                {  
                    if(socket->bytesAvailable()  )  
                    {  
                        qDebug() << "Erreur < sizeof(quint32))";  
                        return;  
                    }  
     
                    in >> blockSize;  
                }  
     
                if(socket->bytesAvailable() < blockSize)  
                 {  
                    qDebug() << "données pas arriver en entier";  
     
                    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::deconnexionClient()  
    {  
        envoyerATous(tr("<em>Un client vient de se déconnecter</em>"));  
     
        // On détermine quel client se déconnecte  
        QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());  
        if (socket == 0) // Si par hasard on n'a pas trouvé le client à l'origine du signal, on arrête la méthode  
            return;  
     
        clients.removeOne(socket);  
     
        socket->deleteLater();  
    }  
     
    void FenServeur::envoyerATous(const QString &message)  
    {  
        // Préparation du paquet  
        QByteArray paquet;  
        QDataStream out(&paquet, QIODevice::WriteOnly);  
     
        out << (quint16) 0; // On écrit 0 au début du paquet pour réserver la place pour écrire la taille  
        out << message; // On ajoute le message à la suite  
        out.device()->seek(0); // On se replace au début du paquet  
        out << (quint16) (paquet.size() - sizeof(quint16)); // On écrase le 0 qu'on avait réservé par la longueur du message  
     
     
        // Envoi du paquet préparé à tous les clients connectés au serveur  
        for (int i = 0; i < clients.size(); i++)  
        {  
            clients[i]->write(paquet);  
        }  
     
    }
    merci de me corriger.

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 56
    Par défaut
    Bonjour,

    Ce n'est pas vraiment une erreur, la doc Qt précise ici :
    Warning: If you use QSocket or QSocketDevice as the I/O device d for reading data, you must make sure that enough data is available on the socket for the operation to successfully proceed; QDataStream does not have any means to handle or recover from short-reads.
    Mais comme tu as un QDataStream, rien ne t'empêche d'attendre que tout soit arrivé pour lire ou d'ajouter petit à petit ce qui arrive jusqu'à avoir toutes les données. Donc au lieu de faire return ligne 75 sur le serveur, il faut plutôt préciser que les prochaines données sont la suite de ce qui a déjà été lu.
    Après, je ne comprends pas pourquoi ligne 62 (toujours sur le serveur), tu dis qu'il y a un problème quand il y a des données qui sont prêtes à être lues.

Discussions similaires

  1. envoi mail avec fichier joint
    Par dietrich dans le forum API standards et tierces
    Réponses: 14
    Dernier message: 28/02/2006, 14h42
  2. Script d'envoie d'un fichier excel via un formulaire
    Par Morphine.Nw dans le forum ASP
    Réponses: 4
    Dernier message: 26/01/2006, 13h08
  3. Envoi/Reception de fichier sur un reseau
    Par Janitrix dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 19/12/2005, 14h10
  4. Envoie d'un fichier par Internet
    Par gust dans le forum Access
    Réponses: 7
    Dernier message: 07/12/2005, 15h59
  5. [C#] [FTP] Envoi et suppression fichier sur ftp NON ANONYME!
    Par djsbens dans le forum Windows Forms
    Réponses: 14
    Dernier message: 30/03/2005, 10h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo