IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Qt Discussion :

[Sockets] Faire communiquer un client Qt avec un serveur PHP


Sujet :

Qt

  1. #1
    Membre à l'essai
    Inscrit en
    Août 2007
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 24
    Points : 16
    Points
    16
    Par défaut [Sockets] Faire communiquer un client Qt avec un serveur PHP
    Bonjour !

    Cela fait de nombreuses semaines que je galère sur un problème, je dispose qu'une application Qt qui fait office de client de chat, ainsi que d'un serveur de sockets codé en PHP (fonctions socket_*). Le problème c'est que les deux font la gueule on va dire !

    Tout d'abord, quand le client Qt envoie une requête, par exemple :

    PHP reçois :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ����CONNECT
    Bilbax
    test�
    Je suppose que les six premiers caractères sont la taille du message (le quint16) et que le dernier caractère est le caractère NULL indiquant la fin de la chaîne). Après quelque parsages en PHP j'arrive à restituer le message envoyé par le client. Pour l'instant pas de problèmes.

    Par contre. Quand il est question que PHP renvoie une réponse au client, ça marche pas du tout. Au moment du socket_write() de PHP le signal « readyRead » de la socket cliente est émis. Selon bytesAvailable() les données ont été reçues, sauf que la réponse sous forme de QString est vide !

    Voici le slot qui est connecté au signal readyRead :

    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
    void WinConn::datasReceived()
    {
    	QDataStream in(_socket);
     
    	QMessageBox::information(this, "Réception", "Des données ont été reçues. Taille disponible : "+QString::number(_socket->bytesAvailable())+" ; Taille d'une quint16 : "+QString::number((int)sizeof(quint16)));
     
    	if(_msgSize == 0)
    	{
    		if(_socket->bytesAvailable() < (int)sizeof(quint16))
    			return;
    		in >> _msgSize;
    	}
     
    	QString recep;
    	in >> recep;
     
    	QMessageBox::information(this, "Réception", recep);
     
    	_msgSize = 0;
    }
    J'ai énormément besoin de votre aide !
    Ça serait très gentil de m'aider !

    Merci d'avance.

  2. #2
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 42
    Points : 19
    Points
    19
    Par défaut
    Tu cherche la taille du paquet mais tu n'attend pas que celui ci soit entierement chargé ?

  3. #3
    Membre à l'essai
    Inscrit en
    Août 2007
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 24
    Points : 16
    Points
    16
    Par défaut
    Citation Envoyé par poulecaca Voir le message
    Tu cherche la taille du paquet mais tu n'attend pas que celui ci soit entierement chargé ?
    Oh mon Dieu j'ai complètement oublié ça Merci.

    Mais c'est pas pour ça que ça marche maintenant :

    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
    void WinConn::datasReceived()
    {
    	QDataStream in(_socket);
     
    	QMessageBox::information(this, "Réception", "Des données ont été reçues. Taille disponible : "+QString::number(_socket->bytesAvailable())+" ; Taille d'une quint16 : "+QString::number((int)sizeof(quint16)));
     
    	if(_msgSize == 0)
    	{
    		if(_socket->bytesAvailable() < (int)sizeof(quint16))
    			return;
    		in >> _msgSize;
    	}
     
    	QMessageBox::information(this, "Taille du message", "La taille du paquet a été reçue : "+QString::number(_msgSize));
     
    	if(_socket->bytesAvailable() < _msgSize)
    		return;
     
    	QString recep;
    	in >> recep;
     
    	QMessageBox::information(this, "Réception", recep);
     
    	_msgSize = 0;
    }
    Ce code m'indique que la taille du paquet qu'à envoyé PHP est de 17231 (!!!) ce qui est énorme comparée à la réponse normale !

    Mais je sais à quoi c'est dû. En fait PHP n'envoie pas la taille du message comme le fait Qt en début de paquet, alors Qt lit le début de la réponse PHP comme étant la taille du paquet, c'est pour ça qu'il retourne n'importe quoi (17231), par contre je ne sais pas comment faire en PHP pour mettre la taille du paquet au début de celui-ci !

  4. #4
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Et si tu wrappais l'envoi d'une chaîne dans un socket en insérant toi-même le header (ici la taille du message) ? Et après dans ton code PHP tu n'appelles QUE cette fonction au lieu de socket_write().

  5. #5
    Membre à l'essai
    Inscrit en
    Août 2007
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 24
    Points : 16
    Points
    16
    Par défaut
    Merci de ta réponse, mais je n'ai aucune idée de comment faire ce que tu m'a dis.

    Donc je dois créer une fonction perso qui va envoyer une socket personnalisée avec en-tête la taille du message (quint16) ? Faudra me donner plus de pistes car là je suis dans le pétrain

  6. #6
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Tu écris une fonction PHP qui appelle socket_write mais qui insère un header contenant ce que tu veux dans la chaîne à envoyer, et tu transmets le résultat à socket_write.

  7. #7
    Membre à l'essai
    Inscrit en
    Août 2007
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 24
    Points : 16
    Points
    16
    Par défaut
    Ok mais je sais pas comment insérer un header dans une socket Et la doc ne me donne rien d'intéressant...

    Donc le header contiendra la taille du message ?

  8. #8
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Oui ! Ca donnerait quelque chose comme (grossièrement hein) :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function mywrite($socket, $a_envoyer)
    {
      $new_var = strlen($a_envoyer) . '|' . $a_envoyer;
      socket_write($socket, $new_var); // en supposant que c'est le bon prototype pour socket_write
    }

  9. #9
    Membre à l'essai
    Inscrit en
    Août 2007
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 24
    Points : 16
    Points
    16
    Par défaut
    Ça ne marche pas, la pipe est considérée comme faisant parti du message

  10. #10
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    J'ai mis '|' mais je ne sais pas comment Qt formatte. Il faut que ce soit identiquement formé aux chaînes envoyées par le client Qt !

  11. #11
    Membre à l'essai
    Inscrit en
    Août 2007
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 24
    Points : 16
    Points
    16
    Par défaut
    Sauf que je n'ai aucune idée de comment peut bien être stocké la taille du message sous cette forme : « ���� », c'est comme ça que Qt envoie, il faut que je comprenne comment ça peut contenir la taille du message pour ensuite faire pareil en PHP pour l'envoie.

    Et je suppose que je dois aussi envoyer le caractère « � » en fin de chaîne comme me l'envoie Qt ?

    function socket_reponse($socket, $str)
    {
    socket_write($socket, fonctionMagiquePourConvertirLeNombreEnCaracteresBizareQuiPourontEtreLusParQt(strlen($str)).$str.'�');
    }

    (Balise [code] boguée)

    Il faut maintenant trouver comment coder cette fonction magique

  12. #12
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 2
    Points : 2
    Points
    2
    Par défaut Solution
    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
    function QtPack($input)
    {
    	$input = mb_convert_encoding($input, "UTF-16", "ISO-8859-1");
    	$return = pack("nN", strlen($input)+4, strlen($input)).$input;
    	return $return;
    }
     
    function QtSend($playersock, $output)
    {
    	$output = QtPack('A'.$output);
    	socket_write($playersock, $output);
    }
     
    function QtUnPack($input)
    {
    	$input = mb_convert_encoding($input, "ISO-8859-1", "UTF-16");
    	$input = substr($input,3);
    	return $input;
     }
     
    // Utilisation :
     
    $input = socket_read($j[$i]['sock'] , 1024);
    $input = QtUnPack($input);
     
    // Traiter $input et retourner $output
     
    QtSend($j[$i]['sock'], $output);

  13. #13
    Membre à l'essai
    Inscrit en
    Août 2007
    Messages
    24
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 24
    Points : 16
    Points
    16
    Par défaut
    C'est marrant car j'avais trouvé cette solution (la même !) il y a quelque jours sur Internet, mais comme ce problème n'était plus d'actualité je me suis dit que ça servirait à rien.

    En tout cas merci à toi, je laisse dans mes favoris cette page et je saurais où aller la prochaine fois que j'ai besoin d'établir une communication entre Qt et PHP .

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Faire communiquer une application lourde avec un serveur Web
    Par oneagaindoguys dans le forum Développement Web en Java
    Réponses: 7
    Dernier message: 15/08/2011, 11h36
  2. Réponses: 4
    Dernier message: 11/11/2010, 23h30
  3. Faire communiquer un formulaire parent avec une popup
    Par shgeoffrey dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 05/04/2008, 19h20
  4. Faire communiquer Axapta(Dynamics Ax) avec une autre application
    Par Access Newbie dans le forum Microsoft Dynamics
    Réponses: 5
    Dernier message: 13/12/2007, 15h52
  5. Réponses: 3
    Dernier message: 27/07/2006, 09h17

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo