Communication réseau client/serveur

Question

Concevez une application serveur et une application cliente dont les IHM sont conformes aux suggestions ci-dessous.

Le client comme le serveur doit pouvoir émettre et recevoir des informations.

La gestion des erreurs de communication doit être effective.

IHM de l'application client TCP
IHM de l'application client TCP
IHM de l'application serveur TCP
IHM de l'application serveur TCP

Indice

Tout est dans la formation (page précédente).

SD des deux programmes à réaliser (diagramme de classes)
SD des deux programmes à réaliser (diagramme de classes)

Solution

Le fichier CServeurTcp.h

Il s'agit de la définition de la classe de gestion du serveur TCP.

CServeurTcp s'occupe :

  • D'initialiser/détruire le serveur TCP sur le port choisi.

  • Se met à l'écoute des clients.

  • Mémorise chaque client connecté.

  • Communique avec la classe IHM (CIhmAppServeurTcp) par des signaux/slots.

1
#ifndef CSERVEURTCP_H
2
#define CSERVEURTCP_H
3
4
#include <QTcpServer>
5
#include <QTcpSocket>
6
#include <QDebug>
7
8
#define PORTPARDEFAUT 2222
9
10
class CServeurTcp : public QTcpServer
11
{
12
    Q_OBJECT
13
public:
14
    explicit CServeurTcp(QObject *parent = 0);
15
    explicit CServeurTcp(QObject *parent = 0, quint16 noPort = 2222);
16
    ~CServeurTcp();
17
    int emettreVersClients(QString mess);
18
19
signals:
20
    void sigEvenementServeur(QString eve);
21
    void sigErreur(QAbstractSocket::SocketError err);
22
    void sigDataClient(QString adrIpClient, QString data);
23
    void sigAdrClient(QString adrClient);
24
    void sigMaJClients(QList<QTcpSocket *> liste);
25
26
public slots:
27
    void onNewConnectionClient();
28
    void onDisconnectedClient();
29
    void onErreurReseau(QAbstractSocket::SocketError err);
30
    void onReadyReadClient();
31
32
private:
33
    int init();
34
    quint16 m_noPort;
35
    QList<QTcpSocket *> listeClients;
36
};
37
38
#endif // CSERVEURTCP_H

Vous notez qu'il y a 2 constructeurs, dont 1 paramétré. Par défaut, c'est le port PORTPARDEFAUT qui sera utilisé.

5 signaux sont gérés :

  • sigEvenementServeur : Pour informer l'IHM d'une connexion/déconnexion d'un client.

  • sigDataClient : Pour envoyer les données reçues vers l'IHM.

  • sigErreur : Pour signaler une erreur réseau.

  • sigAdrClient : Pour envoyer l'adresse IP du client connecté.

  • sigMaJClients : Pour envoyer la liste des clients connectés au serveur.

4 slots sont gérés :

  • onNewConnectionClient() : S'exécute lors de la connexion d'un nouveau client.

  • onDisconnectedClient() : S'exécute lors de la déconnexion d'un client.

  • onErreurReseau() : S'exécute en cas d'erreur réseau.

  • onReadyReadClient() : S'exécute lorsqu'un client émet des caractères.

Le fichier CServeurTcp.cpp

Il contient la définition des méthodes de la classe CServeurTcp.

1
#include "cserveurtcp.h"
2
3
CServeurTcp::CServeurTcp(QObject *parent) :
4
    QTcpServer(parent)
5
{
6
    m_noPort = PORTPARDEFAUT;
7
    init();
8
}
9
10
CServeurTcp::CServeurTcp(QObject *parent, quint16 noPort) :
11
    QTcpServer(parent)
12
{
13
    m_noPort = noPort;
14
    init();
15
}
16
17
CServeurTcp::~CServeurTcp()
18
{
19
    // destruction optionnelle car déjà pris en charge par le serveur
20
    for (int i=0 ; i<listeClients.size() ; i++) {
21
        listeClients.at(i)->close();
22
        delete listeClients.at(i);
23
    } // for i
24
}
25
26
int CServeurTcp::emettreVersClients(QString mess)
27
{
28
    for (int i=0 ; i<listeClients.size() ; i++) {
29
        listeClients.at(i)->write(mess.toStdString().c_str());
30
        qDebug() << "Envoi vers " << listeClients.at(i);
31
    } // for i
32
    return 1;
33
}
34
35
int CServeurTcp::init()
36
{
37
    listen(QHostAddress::Any, m_noPort);
38
    connect(this,SIGNAL(newConnection()), this, SLOT(onNewConnectionClient()));
39
    connect(this, SIGNAL(acceptError(QAbstractSocket::SocketError)), this, SLOT(onErreurReseau(QAbstractSocket::SocketError)));
40
    return 1;
41
}
42
43
///////////////////  SLOTs ////////////////////////
44
45
void CServeurTcp::onNewConnectionClient()
46
{
47
    QString mess="Un client vient de se connecter";
48
    qDebug() << mess;
49
    QTcpSocket *newClient = this->nextPendingConnection();
50
    qDebug() << "Nouvelle connexion : " << newClient;
51
    if (newClient == NULL)
52
        emit sigErreur(QAbstractSocket::ConnectionRefusedError);
53
    connect(newClient, SIGNAL(readyRead()), this, SLOT(onReadyReadClient()));
54
    connect(newClient, SIGNAL(disconnected()), this, SLOT(onDisconnectedClient()));
55
    listeClients.append(newClient);  // sauve l'adresse de l'objet dans la liste
56
    emit sigEvenementServeur("CON");
57
    emit sigAdrClient(newClient->localAddress().toString());
58
    emit sigMaJClients(listeClients);  // pour IHM
59
}
60
61
void CServeurTcp::onDisconnectedClient()
62
{
63
    QTcpSocket *client = (QTcpSocket *)sender(); // Déterminer quel client ?
64
    emit sigEvenementServeur("DEC");
65
    listeClients.removeOne(client);
66
    delete client;
67
    emit sigMaJClients(listeClients);
68
}
69
70
void CServeurTcp::onErreurReseau(QAbstractSocket::SocketError err)
71
{
72
    qDebug() << "Erreur réseau !";
73
    emit sigErreur(err);
74
}
75
76
void CServeurTcp::onReadyReadClient()
77
{
78
    QByteArray ba;
79
    // Déterminer quel client ?
80
    QTcpSocket *client = (QTcpSocket *)sender();
81
    ba=client->readAll();
82
    qDebug() << "Client : " << client << ba.size() << " Caractères reçus.";
83
    emit sigDataClient(client->localAddress().toString(), QString(ba));
84
}
85
86
  • Les constructeurs appellent tous deux la méthode privée init(). Cette méthode initialise le serveur et le prépare à gérer une connexion avec un client.

  • Le destructeur supprime tous les objets clients connecté avant que le serveur ne se termine. Cette action est optionnelle car la documentation signale que l'objet QServeurTcp est conçu pour supprimer automatiquement les objets qu'il a créé. Cependant, la documentation conseille malgré tout de le faire ! ! !

  • emettreVersClients() Permet d'émettre une information à partir du serveur vers tous les clients connectés.

  • onNewConnectionClient() mémorise l'adresse de l'objet du nouveau client connecté et la stocke dans une liste dynamique (QList). La méthode envoie ensuite les signaux pour signifier la connexion, l'adresse IP du client, la liste mise à jour de tous les clients connectés.

  • onDisconnectedClient() gère la déconnexion d'un client en le supprimant, en mettant à jour la liste des clients connectés. La méthode sender() permet d'obtenir l'adresse de l'objet ayant déclenché le slot.

  • onErreurReseau() ne fait qu'émettre le signal vers l'objet appelant (IHM).

  • onReadyReadClient() est exécuté lorsqu'un client envoi des octets au serveur. La méthode sender() est encore utilisée pour savoir quel client a émis l'information. Après lecture des informations reçues, le signal sigDataClient() est émis vers l'IHM.

Le fichier CIhmAppServeurTcp.h

La classe CIhmAppServeurTcp permet de gérer l'IHM de notre application serveur.

1
#ifndef CIHMAPPSERVEURTCP_H
2
#define CIHMAPPSERVEURTCP_H
3
4
#include <QMainWindow>
5
#include <QTcpServer>
6
#include <QTcpSocket>
7
#include <QList>
8
#include "cserveurtcp.h"
9
10
#define PORT 2222
11
12
namespace Ui {
13
class CIhmAppServeurTcp;
14
}
15
16
class CIhmAppServeurTcp : public QMainWindow
17
{
18
    Q_OBJECT
19
20
public:
21
    explicit CIhmAppServeurTcp(QWidget *parent = 0);
22
    ~CIhmAppServeurTcp();
23
24
private slots:
25
    void on_pbEnvoyer_clicked();
26
    void onEvenementServeur(QString eve);
27
    void onDataRecu(QString adrIpClient, QString data);
28
    void onErreurServeur(QAbstractSocket::SocketError err);
29
    void onAdrClient(QString adrClient);
30
    void onListeMaJClients(QList<QTcpSocket *> liste);
31
32
private:
33
    Ui::CIhmAppServeurTcp *ui;
34
    CServeurTcp *serv;
35
};
36
37
#endif // CIHMAPPSERVEURTCP_H
38
  • on_pbEnvoyer_clicked() : Slot permettant l'envoi d'informations vers tous les clients connectés.

  • onEvenementServeur() : Slot permettant l'affichage d'états du serveur TCP (connexion/déconnexion).

  • onDataRecu() : Slot permettant l'affichage des informations reçues d'un client.

  • onErreurServeur() : Slot permettant d'afficher le texte d'une erreur de l'application.

  • onAdrClient() : Slot permettant l'affichage de l'adresse du client nouvellement connecté.

  • onListeMaJClients() : Slot mettant à jour la liste des client dans l'IHM.

  • serv : Pointeur vers le serveur TCP de l'application.

Le fichier CIhmAppServeurTcp.cpp

Définition des méthodes de la classe CIhmAppServeurTcp.

1
#include "cihmappserveurtcp.h"
2
#include "ui_cihmappserveurtcp.h"
3
4
CIhmAppServeurTcp::CIhmAppServeurTcp(QWidget *parent) :
5
    QMainWindow(parent),
6
    ui(new Ui::CIhmAppServeurTcp)
7
{
8
    ui->setupUi(this);
9
    ui->pbEnvoyer->setEnabled(false);
10
11
    serv = new CServeurTcp(this, PORT);
12
    connect(serv,SIGNAL(sigEvenementServeur(QString)), this, SLOT(onEvenementServeur(QString)));
13
    connect(serv, SIGNAL(sigDataClient(QString,QString)), this, SLOT(onDataRecu(QString,QString)));
14
    connect(serv, SIGNAL(sigErreur(QAbstractSocket::SocketError)), this, SLOT(onErreurServeur(QAbstractSocket::SocketError)));
15
    connect(serv, SIGNAL(sigAdrClient(QString)), this, SLOT(onAdrClient(QString)));
16
    connect(serv, SIGNAL(sigMaJClients(QList<QTcpSocket*>)), this, SLOT(onListeMaJClients(QList<QTcpSocket*>)));
17
}
18
19
CIhmAppServeurTcp::~CIhmAppServeurTcp()
20
{
21
    delete serv;
22
    delete ui;
23
}
24
25
void CIhmAppServeurTcp::on_pbEnvoyer_clicked()
26
{
27
    serv->emettreVersClients(ui->leTexte->text());
28
}
29
30
void CIhmAppServeurTcp::onEvenementServeur(QString eve)
31
{
32
    if (eve=="DEC") {
33
        ui->teTexte->append("Déconnexion d'un client.");
34
    }
35
    if (eve=="CON") {
36
        ui->teTexte->append("Connexion d'un client.");
37
        ui->pbEnvoyer->setEnabled(true);
38
    }
39
}
40
41
void CIhmAppServeurTcp::onDataRecu(QString adrIpClient, QString data)
42
{
43
    ui->teTexte->append(adrIpClient+": "+data);
44
}
45
46
void CIhmAppServeurTcp::onErreurServeur(QAbstractSocket::SocketError err)
47
{
48
    switch (err) {
49
      case QAbstractSocket::ConnectionRefusedError:
50
        ui->teTexte->append("Connexion refusée par le serveur !");
51
      break;
52
      case QAbstractSocket::NetworkError:
53
        ui->teTexte->append("Coupure de liaison réseau !");
54
        break;
55
      default:
56
        ui->teTexte->append("Erreur réseau à déterminer !");
57
      break;
58
    } // sw
59
}
60
61
void CIhmAppServeurTcp::onAdrClient(QString adrClient)
62
{
63
    ui->teTexte->append(adrClient+" est connecté.");
64
}
65
66
void CIhmAppServeurTcp::onListeMaJClients(QList<QTcpSocket *> liste)
67
{
68
    ui->cbListe->clear();
69
    for (int i=0 ; i<liste.size() ; i++) {
70
        ui->cbListe->addItem(liste.at(i)->localAddress().toString()+ "->"+QString::number((unsigned long)liste.at(i)));
71
        qDebug() << "CIhmAppServeurTcp::onListeMaJClients"
72
                 << liste.at(i)->localAddress().toString()+ "->"+QString::number((unsigned long)liste.at(i));
73
    } // for i
74
    if (liste.size()==0)
75
        ui->pbEnvoyer->setEnabled(false);
76
}
77
  • Constructeur : Instanciation du serveur TCP de l'application. Captage des signaux du serveur TCP.

  • onListeMaJClients() : Met à jour la liste des clients dans le widget QComboBox.

  • QList : Cette classe permet la gestion d'une liste de n'importe quoi ! C'est pourquoi il faut lui préciser entre <> le type des informations à mémoriser. Dans notre cas, il s'agit d'adresses d'objets clients TCP de type QTcpSocket.

Le fichier CIhmAppServeurTcp.ui

Fichier XML contenant la description de l'IHM du serveur.

1
<?xml version="1.0" encoding="UTF-8"?>
2
<ui version="4.0">
3
 <class>CIhmAppServeurTcp</class>
4
 <widget class="QMainWindow" name="CIhmAppServeurTcp">
5
  <property name="geometry">
6
   <rect>
7
    <x>0</x>
8
    <y>0</y>
9
    <width>1146</width>
10
    <height>1002</height>
11
   </rect>
12
  </property>
13
  <property name="windowTitle">
14
   <string>Serveur TCP de base</string>
15
  </property>
16
  <widget class="QWidget" name="centralWidget">
17
   <widget class="QLineEdit" name="leTexte">
18
    <property name="geometry">
19
     <rect>
20
      <x>20</x>
21
      <y>60</y>
22
      <width>861</width>
23
      <height>61</height>
24
     </rect>
25
    </property>
26
   </widget>
27
   <widget class="QTextEdit" name="teTexte">
28
    <property name="geometry">
29
     <rect>
30
      <x>20</x>
31
      <y>220</y>
32
      <width>1101</width>
33
      <height>671</height>
34
     </rect>
35
    </property>
36
   </widget>
37
   <widget class="QPushButton" name="pbEnvoyer">
38
    <property name="geometry">
39
     <rect>
40
      <x>900</x>
41
      <y>70</y>
42
      <width>215</width>
43
      <height>48</height>
44
     </rect>
45
    </property>
46
    <property name="text">
47
     <string>Envoyer</string>
48
    </property>
49
    <property name="default">
50
     <bool>true</bool>
51
    </property>
52
   </widget>
53
   <widget class="QLabel" name="label_2">
54
    <property name="geometry">
55
     <rect>
56
      <x>20</x>
57
      <y>10</y>
58
      <width>781</width>
59
      <height>39</height>
60
     </rect>
61
    </property>
62
    <property name="text">
63
     <string>Ecoute sur le port 2222</string>
64
    </property>
65
   </widget>
66
   <widget class="QComboBox" name="cbListe">
67
    <property name="geometry">
68
     <rect>
69
      <x>570</x>
70
      <y>140</y>
71
      <width>551</width>
72
      <height>51</height>
73
     </rect>
74
    </property>
75
   </widget>
76
   <widget class="QLabel" name="label">
77
    <property name="geometry">
78
     <rect>
79
      <x>30</x>
80
      <y>140</y>
81
      <width>541</width>
82
      <height>39</height>
83
     </rect>
84
    </property>
85
    <property name="text">
86
     <string>Liste des clients connectés : </string>
87
    </property>
88
    <property name="alignment">
89
     <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
90
    </property>
91
   </widget>
92
  </widget>
93
  <widget class="QMenuBar" name="menuBar">
94
   <property name="geometry">
95
    <rect>
96
     <x>0</x>
97
     <y>0</y>
98
     <width>1146</width>
99
     <height>44</height>
100
    </rect>
101
   </property>
102
  </widget>
103
  <widget class="QToolBar" name="mainToolBar">
104
   <attribute name="toolBarArea">
105
    <enum>TopToolBarArea</enum>
106
   </attribute>
107
   <attribute name="toolBarBreak">
108
    <bool>false</bool>
109
   </attribute>
110
  </widget>
111
  <widget class="QStatusBar" name="statusBar"/>
112
 </widget>
113
 <layoutdefault spacing="6" margin="11"/>
114
 <resources/>
115
 <connections/>
116
</ui>
117
Le fichier CClientTcp.h

Cette classe gère un client réseau.

1
#ifndef CCLIENTTCP_H
2
#define CCLIENTTCP_H
3
4
#include <QObject>
5
#include <QDebug>
6
#include <QTcpSocket>
7
8
class CClientTcp : public QObject
9
{
10
    Q_OBJECT
11
public:
12
    explicit CClientTcp(QObject *parent = 0);
13
    ~CClientTcp();
14
    int emettre(QString mess);
15
    int connecter(QString adr, QString port);
16
    void deconnecter();
17
18
signals:
19
    void sigData(QString data);
20
    void sigErreur(QAbstractSocket::SocketError);
21
    void sigEvenement(QString eve);
22
23
public slots:
24
    void onConnected();
25
    void onDisconnected();
26
    void onReadyRead();
27
    void onSocketError(QAbstractSocket::SocketError);
28
29
private:
30
    QTcpSocket *sock;
31
32
};
33
34
#endif // CCLIENTTCP_H
35

3 signaux sont gérés :

  • sigData() : Pour envoyer les données reçues vers l'IHM.

  • sigErreur() : Pour signaler une erreur réseau.

  • sigEvenement() : Pour informer l'IHM d'une connexion/déconnexion d'un client.

4 slots sont gérés :

  • onConnected() : S'exécute lors de la connexion au serveur.

  • onDisconnected() : S'exécute lors de la déconnexion du client.

  • onSocketError() : S'exécute en cas d'erreur réseau.

  • onReadyRead() : S'exécute lorsque le serveur envoi des informations au client.

Le fichier CClientTcp.cpp
1
#include "cclienttcp.h"
2
3
CClientTcp::CClientTcp(QObject *parent) :
4
    QObject(parent)
5
{
6
    sock = new QTcpSocket(this);
7
    connect(sock, SIGNAL(connected()), this, SLOT(onConnected()));
8
    connect(sock, SIGNAL(disconnected()), this, SLOT(onDisconnected()));
9
    connect(sock, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
10
    connect(sock, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onSocketError(QAbstractSocket::SocketError)));
11
}
12
13
CClientTcp::~CClientTcp()
14
{
15
    delete sock;
16
}
17
18
int CClientTcp::emettre(QString mess)
19
{
20
    int nb = sock->write(mess.toStdString().c_str());
21
    if (nb == -1)
22
        qDebug() << "CClientTcp::emettre Erreur écriture.";
23
    return nb;
24
}
25
26
int CClientTcp::connecter(QString adr, QString port)
27
{
28
    sock->connectToHost(adr, port.toUShort(), QIODevice::ReadWrite);
29
    if (!sock->isOpen())
30
        qDebug() << "CClientTcp::connecter Erreur";
31
    return 1;
32
}
33
34
void CClientTcp::deconnecter()
35
{
36
    sock->close();
37
}
38
39
/////////////  SLOTs /////////////////////////////////////
40
41
void CClientTcp::onConnected()
42
{
43
    qDebug() << "Client connecté.";
44
    emit sigEvenement("CON"); // communication avec IHM
45
}
46
47
void CClientTcp::onDisconnected()
48
{
49
    qDebug() << "Client déconnecté.";
50
    emit sigEvenement("DEC"); // communication avec IHM
51
}
52
53
void CClientTcp::onReadyRead()
54
{
55
    int nb = sock->bytesAvailable();
56
    qDebug() << nb << " octets à lire : ";
57
58
    QByteArray data;
59
    data = sock->readAll();
60
    qDebug() << "CClientTcp::onReadyRead " << data;
61
    emit sigData(QString(data));  // transmission à l'IHM par signal
62
}
63
64
void CClientTcp::onSocketError(QAbstractSocket::SocketError err)
65
{
66
  qDebug() << "CClientTcp::onSocketError erreur !";
67
  emit sigErreur(err);
68
}
69
  • Le constructeur crée un objet QTcpSocket permettant la gestion d'une communication avec le serveur. Le client TCP est préparé à gérer les signaux émis lors de la connexion/déconnexion au serveur, en cas d'erreur réseau, lorsque des informations sont reçues du serveur.

  • connecter() : Utilise la méthode ConnectToHost() pour se connecter au serveur.

  • onReadyRead() : Lit tous les caractères envoyés par le serveur. Le signal sigData() est ensuite émis pour avertir l'IHM de l'arrivée d'informations du serveur.

Le fichier CIhmAppClientTcp.h

Classe de gestion de l'IHM de l'application.

1
#ifndef CIHMAPPCLIENTTCP_H
2
#define CIHMAPPCLIENTTCP_H
3
4
#include <QMainWindow>
5
#include <QTcpSocket>
6
#include "cclienttcp.h"
7
8
namespace Ui {
9
class CIhmAppClientTcp;
10
}
11
12
class CIhmAppClientTcp : public QMainWindow
13
{
14
    Q_OBJECT
15
16
public:
17
    explicit CIhmAppClientTcp(QWidget *parent = 0);
18
    ~CIhmAppClientTcp();
19
20
private slots:
21
    void on_pbConnecter_clicked();
22
    void on_pbEnvoyer_clicked();
23
    void onEvenementClient(QString eve);
24
    void onDataClient(QString data);
25
    void onErrorClient(QAbstractSocket::SocketError err);
26
27
private:
28
    Ui::CIhmAppClientTcp *ui;
29
    CClientTcp *client;
30
};
31
32
#endif // CIHMAPPCLIENTTCP_H
33
Le fichier CIhmAppClientTcp.cpp
1
#include "cihmappclienttcp.h"
2
#include "ui_cihmappclienttcp.h"
3
4
CIhmAppClientTcp::CIhmAppClientTcp(QWidget *parent) :
5
    QMainWindow(parent),
6
    ui(new Ui::CIhmAppClientTcp)
7
{
8
    ui->setupUi(this);
9
    ui->pbConnecter->setEnabled(true);
10
    ui->pbEnvoyer->setEnabled(false);
11
12
    client = new CClientTcp(this);
13
    connect(client, SIGNAL(sigEvenement(QString)), this, SLOT(onEvenementClient(QString)));
14
    connect(client, SIGNAL(sigErreur(QAbstractSocket::SocketError)), this, SLOT(onErrorClient(QAbstractSocket::SocketError)));
15
    connect(client, SIGNAL(sigData(QString)), this, SLOT(onDataClient(QString)));
16
}
17
18
CIhmAppClientTcp::~CIhmAppClientTcp()
19
{
20
    delete client;
21
    delete ui;
22
}
23
24
//////////////////////////////////////  SLOTs ///////////////////////////////////////////
25
/// IHM
26
void CIhmAppClientTcp::on_pbConnecter_clicked()
27
{
28
    if (ui->pbConnecter->text() == "Connexion") {
29
        client->connecter(ui->leAdrServeur->text(), ui->lePortServeur->text());
30
        ui->pbConnecter->setText("Déconnexion");
31
    } else {
32
        client->deconnecter();
33
        ui->pbConnecter->setText("Connexion");
34
    } // else
35
    }
36
37
void CIhmAppClientTcp::on_pbEnvoyer_clicked()
38
{
39
        client->emettre(ui->leEmission->text());
40
        ui->leEmission->clear();
41
        ui->leEmission->setFocus();
42
}
43
44
45
/// AUTRES OBJETS
46
void CIhmAppClientTcp::onEvenementClient(QString eve)
47
{
48
    if (eve == "CON") {
49
        ui->pbEnvoyer->setEnabled(true);
50
        ui->teReception->append("Connecté au serveur");
51
    } // CON
52
    if (eve=="DEC") {
53
        ui->pbEnvoyer->setEnabled(false);
54
        ui->teReception->append("Perte de connexion du serveur");
55
    } // DEC
56
}
57
58
void CIhmAppClientTcp::onDataClient(QString data)
59
{
60
    ui->teReception->append(data);
61
    qDebug() << "CIhmAppClientTcp::onDataClient " << data;
62
}
63
64
void CIhmAppClientTcp::onErrorClient(QAbstractSocket::SocketError err)
65
{
66
    switch (err) {
67
      case QAbstractSocket::ConnectionRefusedError:
68
        ui->teReception->append("Connexion refusée par le serveur !");
69
      break;
70
    case QAbstractSocket::NetworkError:
71
      ui->teReception->append("Coupure de liaison réseau !");
72
    break;
73
    default:
74
        ui->teReception->append("Erreur réseau à déterminer !");
75
      break;
76
    } // sw
77
}
78
Le fichier CIhmAppClientTcp.ui
1
<?xml version="1.0" encoding="UTF-8"?>
2
<ui version="4.0">
3
 <class>CIhmAppClientTcp</class>
4
 <widget class="QMainWindow" name="CIhmAppClientTcp">
5
  <property name="geometry">
6
   <rect>
7
    <x>0</x>
8
    <y>0</y>
9
    <width>1085</width>
10
    <height>764</height>
11
   </rect>
12
  </property>
13
  <property name="windowTitle">
14
   <string>appClientTcp</string>
15
  </property>
16
  <widget class="QWidget" name="centralWidget">
17
   <widget class="QWidget" name="verticalLayoutWidget">
18
    <property name="geometry">
19
     <rect>
20
      <x>10</x>
21
      <y>20</y>
22
      <width>353</width>
23
      <height>151</height>
24
     </rect>
25
    </property>
26
    <layout class="QVBoxLayout" name="verticalLayout">
27
     <item>
28
      <widget class="QLabel" name="laAdr">
29
       <property name="text">
30
        <string>Adresse du serveur : </string>
31
       </property>
32
       <property name="alignment">
33
        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
34
       </property>
35
      </widget>
36
     </item>
37
     <item>
38
      <widget class="QLabel" name="laPort">
39
       <property name="text">
40
        <string>Port du serveur :</string>
41
       </property>
42
       <property name="alignment">
43
        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
44
       </property>
45
      </widget>
46
     </item>
47
    </layout>
48
   </widget>
49
   <widget class="QWidget" name="verticalLayoutWidget_2">
50
    <property name="geometry">
51
     <rect>
52
      <x>360</x>
53
      <y>20</y>
54
      <width>281</width>
55
      <height>151</height>
56
     </rect>
57
    </property>
58
    <layout class="QVBoxLayout" name="verticalLayout_2">
59
     <item>
60
      <widget class="QLineEdit" name="leAdrServeur">
61
       <property name="inputMask">
62
        <string>999.999.999.999</string>
63
       </property>
64
       <property name="text">
65
        <string>192.168.1.47</string>
66
       </property>
67
      </widget>
68
     </item>
69
     <item>
70
      <widget class="QLineEdit" name="lePortServeur">
71
       <property name="inputMask">
72
        <string>99999</string>
73
       </property>
74
       <property name="text">
75
        <string>2222</string>
76
       </property>
77
      </widget>
78
     </item>
79
    </layout>
80
   </widget>
81
   <widget class="QPushButton" name="pbConnecter">
82
    <property name="geometry">
83
     <rect>
84
      <x>670</x>
85
      <y>37</y>
86
      <width>391</width>
87
      <height>121</height>
88
     </rect>
89
    </property>
90
    <property name="text">
91
     <string>Connexion</string>
92
    </property>
93
   </widget>
94
   <widget class="QTextEdit" name="teReception">
95
    <property name="geometry">
96
     <rect>
97
      <x>20</x>
98
      <y>320</y>
99
      <width>1041</width>
100
      <height>321</height>
101
     </rect>
102
    </property>
103
   </widget>
104
   <widget class="QLineEdit" name="leEmission">
105
    <property name="geometry">
106
     <rect>
107
      <x>20</x>
108
      <y>210</y>
109
      <width>811</width>
110
      <height>71</height>
111
     </rect>
112
    </property>
113
   </widget>
114
   <widget class="QPushButton" name="pbEnvoyer">
115
    <property name="geometry">
116
     <rect>
117
      <x>850</x>
118
      <y>210</y>
119
      <width>211</width>
120
      <height>71</height>
121
     </rect>
122
    </property>
123
    <property name="text">
124
     <string>Envoyer</string>
125
    </property>
126
   </widget>
127
  </widget>
128
  <widget class="QMenuBar" name="menuBar">
129
   <property name="geometry">
130
    <rect>
131
     <x>0</x>
132
     <y>0</y>
133
     <width>1085</width>
134
     <height>44</height>
135
    </rect>
136
   </property>
137
  </widget>
138
  <widget class="QToolBar" name="mainToolBar">
139
   <attribute name="toolBarArea">
140
    <enum>TopToolBarArea</enum>
141
   </attribute>
142
   <attribute name="toolBarBreak">
143
    <bool>false</bool>
144
   </attribute>
145
  </widget>
146
  <widget class="QStatusBar" name="statusBar"/>
147
 </widget>
148
 <layoutdefault spacing="6" margin="11"/>
149
 <resources/>
150
 <connections/>
151
</ui>
152