-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfenclient.cpp
158 lines (130 loc) · 5.25 KB
/
fenclient.cpp
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
#include "fenclient.h"
FenClient::FenClient()
{
infoServ = new QHBoxLayout;
infoClient = new QHBoxLayout;
layout = new QVBoxLayout;
ip = new QLabel;
ip->setText("Ip du serveur: ");
port = new QLabel;
port->setText("Port du serveur: ");
pseudoLabel = new QLabel;
pseudoLabel->setText("Pseudo: ");
messageLabel = new QLabel;
messageLabel->setText("Message: ");
listeMessages = new QTextEdit;
boutonConnexion = new QPushButton;
boutonConnexion->setText("Connexion!");
boutonEnvoyer = new QPushButton;
boutonEnvoyer->setText("Envoyer!");
serveurPort = new QSpinBox;
serveurIP = new QLineEdit;
pseudo = new QLineEdit;
message = new QLineEdit;
infoServ->addWidget(ip);
infoServ->addWidget(serveurIP);
infoServ->addWidget(port);
infoServ->addWidget(serveurPort);
infoServ->addWidget(boutonConnexion);
infoClient->addWidget(pseudoLabel);
infoClient->addWidget(pseudo);
infoClient->addWidget(messageLabel);
infoClient->addWidget(message);
infoClient->addWidget(boutonEnvoyer);
layout->addLayout(infoServ);
layout->addWidget(listeMessages);
layout->addLayout(infoClient);
setLayout(layout);
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)));
connect(boutonConnexion, SIGNAL(clicked(bool)), this, SLOT(on_boutonConnexion_clicked()));
connect(boutonEnvoyer, SIGNAL(clicked(bool)), this, SLOT(on_boutonEnvoyer_clicked()));
connect(message, SIGNAL(returnPressed()), this, SLOT(on_boutonEnvoyer_clicked()));
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é
}
// Envoi d'un message au serveur
void FenClient::on_boutonEnvoyer_clicked()
{
QByteArray paquet;
QDataStream out(&paquet, QIODevice::WriteOnly);
// On prépare le paquet à envoyer
QString messageAEnvoyer = tr("<strong>") + pseudo->text() +tr("</strong> : ") + message->text();
out << (quint16) 0;
out << messageAEnvoyer;
out.device()->seek(0);
out << (quint16) (paquet.size() - sizeof(quint16));
socket->write(paquet); // On envoie le paquet
message->clear(); // On vide la zone d'écriture du message
message->setFocus(); // Et on remet le curseur à l'intérieur
}
// Appuyer sur la touche Entrée a le même effet que cliquer sur le bouton "Envoyer"
void FenClient::on_message_returnPressed()
{
on_boutonEnvoyer_clicked();
}
// On a reçu un paquet (ou un sous-paquet)
void FenClient::donneesRecues()
{
/* Même principe que lorsque le serveur reçoit un paquet :
On essaie de récupérer la taille du message
Une fois qu'on l'a, on attend d'avoir reçu le message entier (en se basant sur la taille annoncée tailleMessage)
*/
QDataStream in(socket);
if (tailleMessage == 0)
{
if (socket->bytesAvailable() < (int)sizeof(quint16))
return;
in >> tailleMessage;
}
if (socket->bytesAvailable() < tailleMessage)
return;
// Si on arrive jusqu'à cette ligne, on peut récupérer le message entier
QString messageRecu;
in >> messageRecu;
// On affiche le message sur la zone de Chat
listeMessages->append(messageRecu);
// On remet la taille du message à 0 pour pouvoir recevoir de futurs messages
tailleMessage = 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);
}