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!