Application client

Création des fichiers

Comme pour l'application Serveur on créé les fichiers initiaux, mais la fenêtre cliente sera réalisée avec QT Designer.

  • Création du projet

  • Fichier main.cpp

  • Fenêtre du client clientwin



Codes sources

Clientwin.pro

TEMPLATE = app

QT += widgets network

SOURCES += \

    main.cpp \

    clientwin.cpp


FORMS += \

    clientwin.ui


HEADERS += \

    clientwin.h

Main.cpp

Le main.cpp presque identique au précédent :

#include <QApplication>

#include "clientwin.h"


int main(int argc, char* argv[])

{

    QApplication app(argc, argv);

    clientwin fenetre;

    fenetre.show();

    return app.exec();

}

clientwin.h

La fenêtre a été décrite avec QT Designer. Le choix s'est porté sur une fenêtre de Dialogue (QDialog)

#ifndef CLIENTWIN_H

#define CLIENTWIN_H

#include <QDialog>

#include <QtNetwork>


namespace Ui {

class clientwin;

}


class clientwin : public QDialog

{

    Q_OBJECT

   

public:

    explicit clientwin(QWidget *parent = 0);

    ~clientwin();


private slots :

    void on_connexionBtn_clicked(); // slot de gestion du bouton de connexion

    void on_sendBtn_clicked(); //slot de gestion du bouton d'émission de message

    void on_dataLE_returnPressed(); //slot de gestion de la touche Entrée pour le champ de saisie

    void getserverdata(); // en provenance de la socket, lit la socket et inscrit l'information

    void connecte();

    void deconnecte();

    void erreurSocket(QAbstractSocket::SocketError erreur);


private:

    Ui::clientwin *ui; //fenêtre IHM

    QTcpSocket *socket;

    quint16 tailleMessage;

};

#endif // CLIENTWIN_H

clientwin.cpp

Le fonctionnement est sensiblement le même que pour le serveur

#include "clientwin.h"

#include "ui_clientwin.h"


clientwin::clientwin(QWidget *parent) :

    QDialog(parent),

    ui(new Ui::clientwin)

{

    ui->setupUi(this);

     socket = new QTcpSocket(this); //créé l'instance de QTcpSocket

     connect(socket, SIGNAL(readyRead()), this, SLOT(getserverdata()));//gestion de la donnée serveur

     connect(socket, SIGNAL(connected()), this, SLOT(connecte())); //gestion de signal de connexion

     connect(socket, SIGNAL(disconnected()), this, SLOT(deconnecte())); //gestion de signal de déconnexion

     connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this,                          SLOT(erreurSocket(QAbstractSocket::SocketError)));//gestion de signal d'erreur

     tailleMessage = 0;

}

clientwin::~clientwin()

{

    delete ui;


}

//**************** Slot de connexion **********************************************************

void clientwin::connecte()

{ //lorsque le signal de connexion est reçu du serveur le client affiche un message et les paramétrages
   //ne peuvent plus être modifiés

    ui->messageTE ->append(tr("<em>Connexion réussie !</em>"));

    ui->connexionBtn->setEnabled(false);

    ui->adresseEdit->setEnabled(false);

    ui->portSB->setEnabled(false);

}

//****** Ce qui se passe quand on appuie sur le bouton Connexion ******************************

void clientwin::on_connexionBtn_clicked()

{//l'utilisateur a cliqué sur le bouton de connexion

    ui->messageTE->append("Tentative de connexion ! "); //on ecrit ce qui se passe

    ui->connexionBtn->setEnabled(false);      //on évite les multiclics en dévalidant le bouton

    socket->abort(); //on désactive les connexions précédentes

    socket->connectToHost(ui->adresseEdit->text(), ui->portSB->value());//on se connecte

}


//****** Ce qui se passe quand on appuie sur le bouton envoyer ******************************

void clientwin::on_sendBtn_clicked()

{//l'utilisateur a cliqué sur le bouton envoyer au serveur

    QByteArray paquet;

    QDataStream out(&paquet, QIODevice::WriteOnly);

    QString DonneesAEnvoyer = ui->dataLE->text();

    out<<(quint16) 0; //on réserve l'entete pour la taille des données

    out<<DonneesAEnvoyer;//on ajoute la donnée

    out.device()->seek(0);//on retourne au début

    out<<(quint16)(paquet.size() - sizeof(quint16));

    socket->write(paquet); //on écrit la donnée sur le socket

    ui->dataLE->clear();//on efface le message initial

    ui->dataLE->focusWidget()   ;//et on redonne le focus à la ligne d'édition

}

// Appuyer sur la touche Entrée a le même effet que cliquer sur le bouton "Envoyer"

void clientwin::on_dataLE_returnPressed()

{

    on_sendBtn_clicked();

}

//****** Ce qui se passe quand une donnée arrive *********************************************

void clientwin::getserverdata()

{ // Affiche les données reçues par le serveur

   QDataStream in(socket);

   if (tailleMessage == 0)

       {//taille non recupérée

           if (socket->bytesAvailable() < (int)sizeof(quint16))

                return;


           in >> tailleMessage;

       }


       if (socket->bytesAvailable() < tailleMessage)

           return;

       // On a toutes les infos nécessaires pour le message

       QString message;

       in >> message;

       // On affiche le message chez le client

       ui->messageTE->append(message);


       // On remet la taille du message à 0 pour pouvoir recevoir de futurs messages

       tailleMessage = 0;

}

//**************** Gestion des erreurs de transmission *****************************************************

void clientwin::erreurSocket(QAbstractSocket::SocketError erreur)

{

    switch(erreur) // On affiche un message différent selon l'erreur qu'on nous indique

    {

        case QAbstractSocket::HostNotFoundError:

            ui->messageTE->append(tr("<em>ERREUR : le serveur n'a pas pu être trouvé. Vérifiez l'IP et le port.</em>"));

            break;

        case QAbstractSocket::ConnectionRefusedError:

            ui->messageTE->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:

            ui->messageTE->append(tr("<em>ERREUR : le serveur a coupé la connexion.</em>"));

            break;

        default:

            ui->messageTE->append(tr("<em>ERREUR : ") + socket->errorString() + tr("</em>"));

    }


    ui->connexionBtn->setEnabled(true);

}

//*************** Affiche me message de déconnexion lorsque le serveur a déconnecté le client

void clientwin::deconnecte()

{

    ui->messageTE ->append(tr("<em>Déconnecté du serveur</em>"));

    ui->connexionBtn->setEnabled(true);

    ui->adresseEdit->setEnabled(true);

    ui->portSB->setEnabled(true);

}