Se connecter / S'enregistrer
Votre question

QT- Problème sur tchat

Tags :
  • Serveur
  • Programmation
Dernière réponse : dans Programmation
7 Avril 2011 11:14:24

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

  1. private slots:
  2. void donneesRecues();
  3. void pseudoRecu();
  4. void confirmation();
  5. private:
  6. quint16 tailleMessage;
  7. quint16 taillePseudo;



FenClient.cpp
  1. FenClient::FenClient()
  2. {
  3. connect(boutonConfirmer, SIGNAL(clicked()), this, SLOT(confirmation()));
  4. }
  5.  
  6. void FenClient::confirmation()
  7. {
  8. QByteArray paquetPseudo;
  9. QDataStream outPseudo(&paquetPseudo, QIODevice::WriteOnly);
  10.  
  11. QString pseudoAEnvoyer = tr("<strong>") + pseudo->text();
  12.  
  13. outPseudo << (quint16) 0;
  14. outPseudo << pseudoAEnvoyer;
  15. outPseudo.device()->seek(0);
  16. outPseudo << (quint16) (paquetPseudo.size() - sizeof(quint16));
  17.  
  18. socket->write(paquetPseudo); // On envoie le paquet
  19.  
  20. pseudo->setEnabled(false); // On grise le champs du pseudo
  21. boutonConfirmer->setEnabled(false); //On grise le bouton de confirmation
  22. }
  23.  
  24.  
  25. // Envoi d'un message au serveur
  26. void FenClient::on_boutonEnvoyer_clicked()
  27. {
  28. QByteArray paquet;
  29. QDataStream out(&paquet, QIODevice::WriteOnly);
  30.  
  31. // On prépare le paquet à envoyer
  32. QString messageAEnvoyer = tr("<strong>") + pseudo->text() +tr("</strong> : ") + message->text();
  33.  
  34. out << (quint16) 0;
  35. out << messageAEnvoyer;
  36. out.device()->seek(0);
  37. out << (quint16) (paquet.size() - sizeof(quint16));
  38.  
  39. socket->write(paquet); // On envoie le paquet
  40.  
  41. message->clear(); // On vide la zone d'écriture du message
  42. message->setFocus(); // Et on remet le curseur à l'intérieur
  43. }
  44.  
  45.  
  46. void FenClient::pseudoRecu()
  47. {
  48.  
  49. /* Même principe que lorsque le serveur reçoit un paquet :
  50. On essaie de récupérer la taille du pseudo
  51. Une fois qu'on l'a, on attend d'avoir reçu le pseudo entier (en se basant sur la taille annoncée taillePseudo)
  52. */
  53. QDataStream inPseudo(socket);
  54.  
  55. if (taillePseudo == 0)
  56. {
  57. if (socket->bytesAvailable() < (int)sizeof(quint16))
  58. return;
  59.  
  60. inPseudo >> taillePseudo;
  61. }
  62.  
  63. if (socket->bytesAvailable() < taillePseudo)
  64. return;
  65.  
  66.  
  67. // Si on arrive jusqu'à cette ligne, on peut récupérer le pseudo entier
  68. QString pseudoRecu;
  69. inPseudo >> pseudoRecu;
  70.  
  71. //On affiche le pseudo sur la zone prévue
  72. listPseudo->append(pseudoRecu);
  73. }
  74.  
  75. void FenClient::donneesRecues()
  76. {
  77. /* Même principe que lorsque le serveur reçoit un paquet :
  78. On essaie de récupérer la taille du message
  79. Une fois qu'on l'a, on attend d'avoir reçu le message entier (en se basant sur la taille annoncée tailleMessage)
  80. */
  81. QDataStream in(socket);
  82.  
  83. if (tailleMessage == 0)
  84. {
  85. if (socket->bytesAvailable() < (int)sizeof(quint16))
  86. return;
  87.  
  88. in >> tailleMessage;
  89. }
  90.  
  91. if (socket->bytesAvailable() < tailleMessage)
  92. return;
  93.  
  94.  
  95. // Si on arrive jusqu'à cette ligne, on peut récupérer le message entier
  96. QString messageRecu;
  97. in >> messageRecu;
  98.  
  99. // On affiche le message sur la zone de Chat
  100. listeMessages->append(messageRecu);
  101.  
  102. // On remet la taille du message à 0 pour pouvoir recevoir de futurs messages
  103. tailleMessage = 0;
  104. }




FenServeur.h

  1. public:
  2. void envoyerATous(const QString &message);
  3. void envoyerPseudoATous(const QString &pseudo);
  4. private:
  5. quint16 tailleMessage;
  6. quint16 taillePseudo;



FenServeur.cpp

  1. //on recoit le pseudo
  2. void FenServeur::pseudoRecu()
  3. {
  4.  
  5. // 1 : on reçoit un paquet (ou un sous-paquet) d'un des clients
  6.  
  7. QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());
  8. if (socket == 0) // Si par hasard on n'a pas trouvé le client à l'origine du signal, on arrête la méthode
  9. return;
  10.  
  11. QDataStream inPseudo(socket); // Si tout va bien, on continue : on lit ce que contient la socketPseudo
  12.  
  13. if (taillePseudo == 0) // Si on ne connaît pas encore la taille du pseudo, on essaie de la récupérer
  14. {
  15. if (socket->bytesAvailable() < (int)sizeof(quint16)) // On n'a pas reçu la taille du pseudo en entier
  16. return;
  17.  
  18. inPseudo >> taillePseudo; // Si on a reçu la taille du pseudo en entier, on la récupère
  19. }
  20.  
  21. // Si on connaît la taille du pseudo, on vérifie si on a reçu le message en entier
  22. if (socket->bytesAvailable() < taillePseudo) // Si on n'a pas encore tout reçu, on arrête la méthode
  23. return;
  24.  
  25. // Si ces lignes s'exécutent, c'est qu'on a reçu tout le pseudo : on peut le récupérer !
  26. QString pseudo;
  27. inPseudo >> pseudo;
  28.  
  29. // 2 : on renvoie le message à tous les clients
  30. envoyerPseudoATous(pseudo);
  31.  
  32. }
  33.  
  34. //On recoit un message
  35. void FenServeur::donneesRecues()
  36. {
  37. // 1 : on reçoit un paquet (ou un sous-paquet) d'un des clients
  38.  
  39. // On détermine quel client envoie le message (recherche du QTcpSocket du client)
  40. QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());
  41. if (socket == 0) // Si par hasard on n'a pas trouvé le client à l'origine du signal, on arrête la méthode
  42. return;
  43.  
  44. // Si tout va bien, on continue : on récupère le message
  45. QDataStream in(socket);
  46.  
  47. if (tailleMessage == 0) // Si on ne connaît pas encore la taille du message, on essaie de la récupérer
  48. {
  49. if (socket->bytesAvailable() < (int)sizeof(quint16)) // On n'a pas reçu la taille du message en entier
  50. return;
  51.  
  52. in >> tailleMessage; // Si on a reçu la taille du message en entier, on la récupère
  53. }
  54.  
  55. // Si on connaît la taille du message, on vérifie si on a reçu le message en entier
  56. if (socket->bytesAvailable() < tailleMessage) // Si on n'a pas encore tout reçu, on arrête la méthode
  57. return;
  58.  
  59.  
  60. // Si ces lignes s'exécutent, c'est qu'on a reçu tout le message : on peut le récupérer !
  61. QString message;
  62. in >> message;
  63.  
  64.  
  65. // 2 : on renvoie le message à tous les clients
  66. envoyerATous(message);
  67.  
  68. // 3 : remise de la taille du message à 0 pour permettre la réception des futurs messages
  69. tailleMessage = 0;
  70. }
  71.  
  72. //Envoi du pseudo a tous le monde
  73. void FenServeur::envoyerPseudoATous(const QString &pseudo)
  74. {
  75. QByteArray paquetPseudo;
  76. QDataStream outPseudo(&paquetPseudo, QIODevice::WriteOnly);
  77.  
  78. // Calcul de la taille du pseudo
  79. outPseudo << (quint16) 0;
  80. outPseudo << pseudo;
  81. outPseudo.device()->seek(0);
  82. outPseudo << (quint16) (paquetPseudo.size() - sizeof(quint16));
  83.  
  84. // Envoi du paquet préparé à tous les clients connectés au serveur
  85. for (int i = 0; i < clients.size(); i++)
  86. {
  87. clients[i]->write(paquetPseudo);
  88. }
  89. }
  90.  
  91. void FenServeur::envoyerATous(const QString &message)
  92. {
  93. // Préparation du paquet
  94. QByteArray paquet;
  95. QDataStream out(&paquet, QIODevice::WriteOnly);
  96.  
  97. //Calcul de la taille du paquet
  98. out << (quint16) 0; // On écrit 0 au début du paquet pour réserver la place pour écrire la taille
  99. out << message; // On ajoute le message à la suite
  100. out.device()->seek(0); // On se replace au début du paquet
  101. out << (quint16) (paquet.size() - sizeof(quint16)); // On écrase le 0 qu'on avait réservé par la longueur du message
  102.  
  103.  
  104. // Envoi du paquet préparé à tous les clients connectés au serveur
  105. for (int i = 0; i < clients.size(); i++)
  106. {
  107. clients[i]->write(paquet);
  108. }
  109. }


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!

Autres pages sur : probleme tchat

7 Avril 2011 17:38:14

J'ai remarqué que le programme ne rentrait pas dans la fonction pseudoRecu()

j'ai donc décidé de la supprimer et de traiter ca dans donneesRecues(), mais c'est le même problème, je n'arrive pas a différencier le paquet pseudo du paquet message, donc tout va dans la liste messages....


une idée?

Merci
m
0
l
Tom's guide dans le monde
  • Allemagne
  • Italie
  • Irlande
  • Royaume Uni
  • Etats Unis
Suivre Tom's Guide
Inscrivez-vous à la Newsletter
  • ajouter à twitter
  • ajouter à facebook
  • ajouter un flux RSS