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.



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

}