Bonjour à tous, je code actuellement un petit tchat pour permettre la communication en réseau local ou sur le WAN. Tout fonctionne bien lorsque je clique sur le bouton 'Envoyer', le client envoie le message au serveur et le serveur renvoie le message a tous les clients, message qui s'affiche dans un QTextBox.
Il reste un petit truc qui va pas (ca doit être tout con mais je le vois pas): Lorsque je clique sur le bouton Confirmer, pour envoyer le pseudo au serveur, je récupère le pseudo mais dans la liste des messages, or je voudrai qu'il aille dans la liste prévue a cet effet...
Voici mon code:
FenClient.h
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 private slots: void donneesRecues(); void pseudoRecu(); void confirmation(); private: quint16 tailleMessage; quint16 taillePseudo;
FenClient.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 FenClient::FenClient() { connect(boutonConfirmer, SIGNAL(clicked()), this, SLOT(confirmation())); } void FenClient::confirmation() { QByteArray paquetPseudo; QDataStream outPseudo(&paquetPseudo, QIODevice::WriteOnly); QString pseudoAEnvoyer = tr("<strong>") + pseudo->text(); outPseudo << (quint16) 0; outPseudo << pseudoAEnvoyer; outPseudo.device()->seek(0); outPseudo << (quint16) (paquetPseudo.size() - sizeof(quint16)); socket->write(paquetPseudo); // On envoie le paquet pseudo->setEnabled(false); // On grise le champs du pseudo boutonConfirmer->setEnabled(false); //On grise le bouton de confirmation } // 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 } void FenClient::pseudoRecu() { /* Même principe que lorsque le serveur reçoit un paquet : On essaie de récupérer la taille du pseudo Une fois qu'on l'a, on attend d'avoir reçu le pseudo entier (en se basant sur la taille annoncée taillePseudo) */ QDataStream inPseudo(socket); if (taillePseudo == 0) { if (socket->bytesAvailable() < (int)sizeof(quint16)) return; inPseudo >> taillePseudo; } if (socket->bytesAvailable() < taillePseudo) return; // Si on arrive jusqu'à cette ligne, on peut récupérer le pseudo entier QString pseudoRecu; inPseudo >> pseudoRecu; //On affiche le pseudo sur la zone prévue listPseudo->append(pseudoRecu); } 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; }
FenServeur.h
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 public: void envoyerATous(const QString &message); void envoyerPseudoATous(const QString &pseudo); private: quint16 tailleMessage; quint16 taillePseudo;
FenServeur.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 //on recoit le pseudo void FenServeur::pseudoRecu() { // 1 : on reçoit un paquet (ou un sous-paquet) d'un des clients 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; QDataStream inPseudo(socket); // Si tout va bien, on continue : on lit ce que contient la socketPseudo if (taillePseudo == 0) // Si on ne connaît pas encore la taille du pseudo, on essaie de la récupérer { if (socket->bytesAvailable() < (int)sizeof(quint16)) // On n'a pas reçu la taille du pseudo en entier return; inPseudo >> taillePseudo; // Si on a reçu la taille du pseudo en entier, on la récupère } // Si on connaît la taille du pseudo, on vérifie si on a reçu le message en entier if (socket->bytesAvailable() < taillePseudo) // Si on n'a pas encore tout reçu, on arrête la méthode return; // Si ces lignes s'exécutent, c'est qu'on a reçu tout le pseudo : on peut le récupérer ! QString pseudo; inPseudo >> pseudo; // 2 : on renvoie le message à tous les clients envoyerPseudoATous(pseudo); } //On recoit un message void FenServeur::donneesRecues() { // 1 : on reçoit un paquet (ou un sous-paquet) d'un des clients // On détermine quel client envoie le message (recherche du QTcpSocket du client) 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; // Si tout va bien, on continue : on récupère le message QDataStream in(socket); if (tailleMessage == 0) // Si on ne connaît pas encore la taille du message, on essaie de la récupérer { if (socket->bytesAvailable() < (int)sizeof(quint16)) // On n'a pas reçu la taille du message en entier return; in >> tailleMessage; // Si on a reçu la taille du message en entier, on la récupère } // Si on connaît la taille du message, on vérifie si on a reçu le message en entier if (socket->bytesAvailable() < tailleMessage) // Si on n'a pas encore tout reçu, on arrête la méthode return; // Si ces lignes s'exécutent, c'est qu'on a reçu tout le message : on peut le récupérer ! QString message; in >> message; // 2 : on renvoie le message à tous les clients envoyerATous(message); // 3 : remise de la taille du message à 0 pour permettre la réception des futurs messages tailleMessage = 0; } //Envoi du pseudo a tous le monde void FenServeur::envoyerPseudoATous(const QString &pseudo) { QByteArray paquetPseudo; QDataStream outPseudo(&paquetPseudo, QIODevice::WriteOnly); // Calcul de la taille du pseudo outPseudo << (quint16) 0; outPseudo << pseudo; outPseudo.device()->seek(0); outPseudo << (quint16) (paquetPseudo.size() - sizeof(quint16)); // Envoi du paquet préparé à tous les clients connectés au serveur for (int i = 0; i < clients.size(); i++) { clients[i]->write(paquetPseudo); } } void FenServeur::envoyerATous(const QString &message) { // Préparation du paquet QByteArray paquet; QDataStream out(&paquet, QIODevice::WriteOnly); //Calcul de la taille du paquet 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); } }
Voila, je conclu qu'il ne différencie pas l'envoi d'un pseudo de l'envoi d'un message, j'ai essayé pas mal de trucs mais rien ne fonctionne... je sens que c'est très proche!
Une idée??
Merci!
Partager