Se connecter / S'enregistrer
Votre question

Dialogue C++ / PHP

Tags :
  • Programme
  • Programmation
Dernière réponse : dans Programmation
5 Mars 2007 17:56:27

Bonjour :) 

Voilà, j'ai pour mission de faire dialoguer un programme C++ et un site web.
J'ai donc pensé créer un petit client PHP permettant l'envoie de ligne de commandes (et autres données) via sockets.
Mais j'ai quelques problèmes, j'arrive à faire dialoguer entre eux un serveur PHP et un Client PHP, idem pour deux prog C++, mais impossible de faire réagir mon C++ à mon PHP (ou l'inverse ^^)

Du coté PHP pour mon client, voici comment je procède :

  1. $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
  2.  
  3. $adresse = "127.0.0.1";
  4. $service_port = "67414";
  5.  
  6. echo("Connexion a la socket... <br>");
  7.  
  8. $result = socket_connect($socket, $adresse, $service_port) or die("impossible de se connecter à la socket <br>");
  9.  
  10. echo("resultat du connect : ".$result."<br>");
  11.  
  12. while($out = socket_read($socket, 2048))
  13. {
  14. echo $out;
  15. }
  16.  
  17. socket_close($socket);
  18.  
  19. echo("Socket fermé!<br>");


Le connect est toujours "en attente de 127.0.0.1..."

Du coté de mon code C++ :

  1. #include "stdafx.h"
  2. #include "stdlib.h"
  3. #include "iostream"
  4. #include <winsock2.h>
  5. #pragma comment(lib, "ws2_32.lib")
  6. using namespace std;
  7.  
  8. int _tmain(int argc, _TCHAR* argv[])
  9. {
  10. WSADATA WSAData;
  11. int troc;
  12. troc = WSAStartup(MAKEWORD(2,0), &WSAData);
  13.  
  14. cout<<" _Creation de la socket serveur..."<<endl;
  15. SOCKET sock_serv;
  16. SOCKADDR_IN add_serv;
  17. add_serv.sin_addr.s_addr = INADDR_ANY;
  18. add_serv.sin_family = AF_INET;
  19. add_serv.sin_port = htonl(67414);
  20. sock_serv = socket(AF_INET,SOCK_STREAM,0);
  21. cout<<" _Socket serveur cree!"<<endl;
  22.  
  23. SOCKET sock_client;
  24. SOCKADDR_IN add_client;
  25.  
  26. if( bind( sock_serv, (SOCKADDR *)&add_serv, sizeof( add_serv ) ) == SOCKET_ERROR ){
  27. cerr<<"bind a échoué avec l'erreur "<< WSAGetLastError()<< endl;
  28. cerr<<"Le port est peut-être déjà utilisé par un autre processus "<< endl;
  29. closesocket( sock_serv );
  30. WSACleanup();
  31. return 1;
  32. }
  33. else
  34. cout<<" _Bind OK!"<<endl;
  35.  
  36. if( listen(sock_serv, 0) == SOCKET_ERROR ){
  37. cerr<<"listen a échoué avec l'erreur "<< WSAGetLastError()<< endl;
  38. closesocket(sock_serv);
  39. WSACleanup();
  40. return 1;
  41. }
  42. else
  43. cout<<" _Listen OK!"<<endl;
  44.  
  45. cout<<" _Serveur correctement demarre!"<<endl;
  46.  
  47. int longu = sizeof(add_client);
  48.  
  49. while(1)
  50. {
  51. cout<<" _Attente de l'acceptation de la connection..."<<endl;
  52. if((sock_client=accept(sock_serv,(SOCKADDR *)&add_client,&longu))!=INVALID_SOCKET)
  53. {
  54. cout<<"Socket Thread connecte!"<<endl;
  55.  
  56. char *requete = new char[10];
  57. int lg;
  58.  
  59. requete = "bonjour lecteur!\0";
  60. lg=strlen(requete);
  61. cout<<" _Longueur chaine : "<<lg<<endl;
  62. send(sock_client,requete,lg,0);
  63. }
  64. else
  65. cout<<"Socket Thread non connecte!"<<endl;
  66.  
  67. closesocket(sock_serv);
  68. closesocket(sock_client);
  69. cout<<" _Socket fermee!"<<endl;
  70.  
  71. system("pause");
  72. return 0;
  73. }



Voilà voilà :) 
Est-il possible de dialoguer entre ces deux language par cette méthode?

Merci d'avance de vos réponses!

Autres pages sur : dialogue php

a b L Programmation
5 Mars 2007 19:11:16

Les sockets ne sont pas dépendant des langages. Donc, normalement ça devrait fonctionner.
Quelle erreur indique le client ?
5 Mars 2007 20:43:17

Hello CRicky!

Merci de ta reponse, ni le client ni le serveur ne retourne d'erreur, ils attendent simplement des nouvelles l'un de l'autre ^^

Mon serveur c++ est en attente de l'acceptation sock_client=accept....

Pendant que dans la barre des tâche de Firefox, sur mon client php on à le droit a un petit "En attente de 127.0.0.1..."

Si ça peut t'aider...
Moi je ne vois pas...
Contenus similaires
a b L Programmation
5 Mars 2007 20:58:55

Le connect doit sortir en time-out (de 75secondes par défaut). Donc, le client n'attend jamais indéfiniment.
S'il y a un time-out, c'est que la connexion ne s'établit pas parce qu'il ne trouve rien.
Peut-être que les ports sont différents.
Lance un client PHP/Serveur PHP, puis client C/Serveur C, avec "netstat -a" regarde si les ports (et protocoles) sont les mêmes dans les 2 cas.
5 Mars 2007 21:16:21

un port est un numéro compris entre 1 et 65535
il faut utiliser un n° > 1024 en tant qu'utilisateur
tu utilises le 67414, c'est en dehors de la limite
a b L Programmation
5 Mars 2007 21:26:58

Ah oui, je n'avais même pas vu ça :D 
Et bien c'est ça le problème ;) 
5 Mars 2007 21:33:42

Hum...
Merci Coca25 et CRicky, ce qui est bizare c'est que ce port marche nikel pour un dialogue PHP/PHP ou C++/C++ ^^

Je vais tenter avec un port différent!

Merci bien :D 
5 Mars 2007 21:44:46

au risque de dire une connerie, je crois que c'est du à l'affectation d'un long sur un short (d'ailleurs il faudrait changer htonl par htons)
67414 etant supérieur à la limite d'un short, le nombre resultant reste le meme pour 2 programmes de C et 2 prog de php
mais bon faut quand même eviter :) 
a b L Programmation
5 Mars 2007 22:48:16

Oui, l'un des deux doit faire un 67414 % 65536, un autre retourne peut-être -1 (65535). Ce ne sont que des hypothèses qui peuvent être confirmée ou non avec le "netstat -a"
6 Mars 2007 09:52:16

Bonjour bonjour :) 

Merci pour vos réponses éclairées ^^
J'ai changé de port, je suis passé au port 64535.
Les dialogues PHP/PHP et C++/C++ fonctionnent toujours, mais C++/PHP non!

Suite à un netstat, voici ce que j'obtient lorsque le seveur C++ et le client PHP sont lancés :

TCP Moi:1194 localhost:64535 ESTABLISHED
TCP Moi:64535 localhost:1193 TIME_WAIT
TCP Moi:64535 localhost:1194 ESTABLISHED

La même chose lorsque seul le serveur C++ est lancé :

TCP Moi:1194 localhost:64535 ESTABLISHED
TCP Moi:64535 localhost:1194 ESTABLISHED

Et plus rien sur localhost lorsque les deux sont kickés.
Bon je ne connais pas grand chose en réseau ^^, éclairez moi une fois de plus s'il vous plait :D 

Le port apres localhost correspond bien à celui que je spécifie dans mon programme, qu'il soit C++ ou PHP, mais le port suivant l'hostname de mon PC, ici 1164 ou 1193, à quoi correspond t-il?
Ensuite, pourquoi j'ai trois infos sur localhost quand je lance mon serveur et mon client?Un novice comme moi ne s'attendrait à en voir seulement deux :) 

Encore de grandes interrogations ^^

Merci de votre aide!

edit :

Lors d'un dialogue PHP/PHP j'obtiens ceci:

TCP Moi:64535 localhost:1560 TIME_WAIT
TCP Moi:64535 localhost:1563 TIME_WAIT
TCP Moi:64535 localhost:1564 TIME_WAIT
6 Mars 2007 13:46:33

le port différent de 64535 correspond à celui du client, port aléatoire entre 1025-65535
le TIME_WAIT correspond à une connexion rompue (je crois)

sur ton programme que tu as posté, je sais pas si c'est une erreur de frappe mais le while n'est pas fermé, faudrait vérifier ca

Citation :

La même chose lorsque seul le serveur C++ est lancé :

TCP Moi:1194 localhost:64535 ESTABLISHED
TCP Moi:64535 localhost:1194 ESTABLISHED

la il y a un client qui est lancé?? sinon tu ne devrais pas avoir ces lignes...
6 Mars 2007 13:48:05

Non il n'y avait pas de client ^^

edit : et la fermeture du while est une erreur de copier coller
6 Mars 2007 13:52:47

en fait je viens de remarquer autre chose, t'aurais pas des warning à la compilation de ton prog en C
tu ne peux affecter directement une chaine de caractère, il faut utiliser strcpy
surtout qu'en plus, requete fait 10 caractères et tu lui affectes une ligne de plus de 10 !!
6 Mars 2007 14:06:01

Oui j'ai effectivement une erreur , mais pas sur l'affectation de chaine de caractère :

warning C4267: '=' : conversion from 'size_t' to 'int', possible loss of data
Linking...

sur : lg=strlen(requete);

J'avoue que ça m'a choqué l'histoire des 10caractères de requete, mais bon, puisque ça passe, pour le moment je ne m'en occupe pas ^^

C'est vraiment cette histoire de dialogue C++/PHP qui me chagrine...
Je viens de relancer un netstat avec mon serveur C++ seul, et les lignes

TCP Moi:1194 localhost:64535 ESTABLISHED
TCP Moi:64535 localhost:1194 ESTABLISHED

ne sont plus presentes...

Par contre j'ai en localhost ce qui suit :

TCP Moi:1068 localhost:1069 ESTABLISHED
TCP Moi:1069 localhost:1068 ESTABLISHED
TCP Moi:1070 localhost:1071 ESTABLISHED
TCP Moi:1071 localhost:1070 ESTABLISHED

Je viens pourtant de kicker tout ce qui aurais pu avoir une quelconque interaction sur local host (easyphp et tout le reste).

Je vais essayer maintenant de lancer le client php (apres redemarrage de easyphp bien sur ^^)

Bon en fait je reboot, easyphp est dans les choux :/ 
6 Mars 2007 14:25:05

le probleme, c'est qu'en C, quand ca passe, c'est pas forcement bon.
le programmeur a pas mal de liberte, mais s'il n'est pas rigoureux, ca foire
(ah les segmentation fault....)

je t'explique, tu alloues un espace de 10 caractères (donc 9 avec le caractère de terminaison), ensuite tu en écris plus de 9, donc le programme écrit sur un espace mémoire indétérminé ce qui peut causer des dysfonctionnements graves même pour le système.

donc commence d'abord par arranger le code, genre des short quand il faut, bien déclarer les chaînes de caractères etc...
6 Mars 2007 14:26:01

Allez hop, le netstat apres reboot :

Citation :
Proto Adresse locale Adresse distante Etat

Rien :) 

Demarrage de easyphp :

Citation :
Proto Adresse locale Adresse distante Etat

Rien :) 

Lancement du serveur seul :

Citation :
Proto Adresse locale Adresse distante Etat

Rien :) 

Lancement du client PHP apres demarrage du serveur C++ :

Citation :
Proto Adresse locale Adresse distante Etat
TCP Moi:http localhost:1041 ESTABLISHED
TCP Moi:http localhost:1042 ESTABLISHED
TCP Moi:1037 localhost:1038 ESTABLISHED
TCP Moi:1038 localhost:1037 ESTABLISHED
TCP Moi:1039 localhost:1040 ESTABLISHED
TCP Moi:1040 localhost:1039 ESTABLISHED
TCP Moi:1041 localhost:http ESTABLISHED
TCP Moi:1042 localhost:http ESTABLISHED
TCP Moi:1043 localhost:64535 ESTABLISHED
TCP Moi:64535 localhost:1043 ESTABLISHED

Ca pique :D 
A noter que rien ne marche...Enfin ce n'est pas tout a fait vrai!Mon C++ a accepté la connexion, et apparement le

message a été envoyé, par contre rien de reçut...Ca fait maintenant plus d'une minute que php semble attendre en

boucle, pas de timeout...Toujours attente de 127.0.0.1

Et le meilleur reste à venir, je kick le client php et oh joie, oh merveille :

Citation :
Proto Adresse locale Adresse distante Etat
TCP Moi:http localhost:1042 CLOSE_WAI
TCP Moi:1038 localhost:1037 TIME_WAIT
TCP Moi:1042 localhost:http FIN_WAIT_
TCP Moi:1043 localhost:64535 ESTABLISH
TCP Moi:64535 localhost:1043 ESTABLISH
TCP Moi:1044 192.168.43.1:8080 TIME_WAIT

Et si je kick aussi le serveur C++... :

Plus rien!
C'est grave docteur?
Toute ces connexions?
Qu'il reste deux connexions ESTABLISH même apres kickage du client?
Je débute, je tiens à le rappeler ^^
6 Mars 2007 14:51:42

Hop encore moi :) 

Ca y est, ça fonctionne ^^
J'ai simplement remplacé la fonction socket_read par la fonction socket_recv dans mon code php!

Je vais maintenant m'attaquer aux petits soucis de code malpropre que tu m'a fais remarquer coca25!

Merci beaucoup pour votre aide tout le monde :D 
a b L Programmation
6 Mars 2007 19:06:32

Juste pour info le principe des socket :
c'est la fonction bind qui permet d'associer un port à une socket. Si le bind n'est pas précisé, le port est aléatoire.
- Le serveur crée une socket 64535 (par bind) en attente.
- Le client crée une socket avec un nombre aléatoire (par exemple 1050)
- Lorsque la connexion (entre la socket client 1050 et serveur 64535) s'effectue, le serveur crée une nouvelle socket (le retour de la fonction accept(), par exemple 1100), et débranche le lien pour le rebrancher sur la nouvelle socket.
Au final la socket client (1050) est connectée à la nouvelle socket serveur (1100).
Et donc, la socket 64535 est libérée, ce qui permet de refaire une connexion avec de nouveaux clients.
Ce mécanisme est transparent pour le client car une fois la socket connecté, il se contente de communiquer dans la socket (peu importe la port qui est au bout).
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