communication code php et C via sockets

communication code php et C via sockets - C - Programmation

Marsh Posté le 12-02-2006 à 17:59:50    

Salut !
 
Alors, voila mon problème. J'ai crée un serveur en C qui attend des données de nimporte quel client.
Voici son code :  
 

Code :
  1. int web ()
  2.     //Declaration des variables locales propres aux sockets !
  3.     WSADATA WSAData;       //Propre à Winsock2       
  4.     SOCKET sock_ecoute;    //Identifiant de la socket d'écoute
  5.     SOCKET sock_trait;     //Identifiant de la socket de traitement
  6.     SOCKADDR_IN adr;       //Structure de la socket locale  
  7.     SOCKADDR_IN appelant;  //Structure de la socket distante
  8.     int lg_app;            //Taille de la structure appelante
  9.     int count;             //Nombre d'octets reçus sur la socket
  10.     char buffer[16];       //Buffer de réception
  11.     fd_set ensemble;
  12.     struct timeval timeout={5,0};
  13.    
  14.     //On démarre l'appli winsock2 nécessaire à l'utilisation de sockets sous windows
  15.     if(WSAStartup(MAKEWORD(2,0), &WSAData) != 0)
  16.     {
  17.       printf("Impossible d'initialiser l'API Winsock 2.0\n" );
  18.       return 0;
  19.     }
  20.    
  21.     //On crée une nouvelle socket TCP  
  22.     sock_ecoute = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
  23.     if(sock_ecoute==INVALID_SOCKET)
  24.     {
  25.       printf("Echec de création de la socket !\n" );   
  26.       return 0;
  27.     }
  28.    
  29.     //On remplit la structure de notre socket
  30.     adr.sin_addr.s_addr = INADDR_ANY;  //On accepte des connexions de nimporte qui
  31.     //adr.sin_addr.s_addr = inet_addr("127.0.0.1" );
  32.     adr.sin_family = AF_INET;          //Application basée sur TCP/IP
  33.     adr.sin_port = htons(PORT);        //PORT définit dans main.h
  34.    
  35.     //On attache la socket à notre structure
  36.     if(bind(sock_ecoute, (SOCKADDR *)&adr, sizeof(adr)) !=0)
  37.     {
  38.       printf("Impossible d'attacher la socket\n" );           
  39.       return 0;
  40.     }
  41.    
  42.     //On place notre socket en écoute
  43.     if(listen(sock_ecoute, 0) !=0 )
  44.     {
  45.       printf("L'écoute sur la socket a échoué\n" );
  46.       return 0;
  47.     }
  48.     lg_app=sizeof(appelant);
  49.    
  50.     while(1)   //Boucle infinie, la seule façon de quitter est ctrl+c
  51.     {
  52.        printf("En attente d'une connexion\n" );
  53.      
  54.        //On attend qu'un client se connecte (fonction bloquante)   
  55.        sock_trait = accept(sock_ecoute, (SOCKADDR *)&appelant, &lg_app);
  56.        if(sock_trait==INVALID_SOCKET)
  57.        {
  58.          printf("Impossible d'accepter la connection entrante\n" );
  59.          return 0;
  60.        }
  61.        printf("\n\nConnecté !\n\n" );
  62.        //Le processus vient d'accepter une connexion, il ne pourra pas en recevoir
  63.        //d'autre tant que cette communication ci ne sera pas terminée  
  64.      
  65.        do
  66.        {
  67.           printf("\n\nEn attente de requètes de %s\n",inet_ntoa(appelant.sin_addr));
  68.           memset(buffer,0,sizeof(buffer));
  69.          
  70.           FD_ZERO(&ensemble);
  71.           FD_SET(sock_trait,&ensemble);
  72.           printf("%d",select(0, &ensemble, 0, 0, &timeout));
  73.           if(FD_ISSET(sock_trait,&ensemble)!=0)
  74.           {
  75.            printf("Des données sont arrivées.\n" );
  76.            count=recv(sock_trait,buffer,16*sizeof(char),0);
  77.            buffer[count]='\0';
  78.            printf("Info reçue : %s sur %d octets\n",buffer,count);
  79.           }
  80.           else
  81.           {
  82.            printf("Toujours rien.\n" );
  83.           }
  84.      }while(count>0);
  85.        //Si on sort de cette boucle, c'est que le client s'est déconnecté
  86.      
  87.        printf("\nLe client vient de fermer la socket\n" );
  88.        //On ferme la socket de traitement, et on retourne en attente de connexion
  89.        close(sock_trait); 
  90.      
  91.     }//Fin de la boucle infinie
  92.    
  93. }//Fin de web


 
 
De l'autre coté, j'ai un code PHP qui est censé envoyé des données à mon programme à partir d'un formulaire. Le voici (en partie):  
 

Code :
  1. <?php
  2. $Serveur = "127.0.0.1";
  3. $Port = 8080;
  4. $ma_socket = pfsockopen($Serveur, $Port);// on crée la socket
  5. if(isset($_POST['bye']))
  6. {
  7. fclose($ma_socket);
  8. $ma_socket=0;
  9. }
  10. if($ma_socket<=0)
  11. echo '<font color="#FF0000"><b> Probleme de connexion avec le programme </b></font><br/>';
  12. else
  13. {
  14. echo '<font color="#009900"><b> Connecté au programme </b></font><br/>';
  15.  if(isset($_POST['var']))
  16.  {
  17.  if(fputs($ma_socket, $_POST['var']))
  18.  echo 'envoyé : $_POST['var'];
  19.  }
  20.         }
  21. ?>


 
 
Voila...
Tout ceci fonctionne parfaitement... mais pendant une durée limitée seulement !
En gros, je lance mon serveur (programme en C), puis, je lance firefox et me connecte à mon site en local (j'ai easy php), je sélectionne une valeur dans un menu déroulant qui l'envoie au code php ci-dessus, et ce dernier l'envoie bel et bien à mon serveur qui m'affiche la valeur choisie.
Je peux répeter cette opération autant de fois que je le veux sans qu'il y ait probleme.
Par contre, si je n'envoie plus rien pendant environ 15 secondes, mon serveur se bloque en réception et j'ai beau envoyé des données, le serveur s'en tête à m'afficher : "toujours rien" toutes les 5 secondes.
Alors, je suppose que soit mon code php soit mon code C crée une socket avec un timeout par défaut d'environ 15 secondes, mais, je trouve ça vraiment bizzare.
J'espère avoir été clair.
Comment faire pour pouvoir envoyer des données sans qu'une interruption bloque mon programme ? Quelqu'un aurait-il une idée ? Merci d'avance.

Reply

Marsh Posté le 12-02-2006 à 17:59:50   

Reply

Marsh Posté le 12-02-2006 à 19:37:14    

krocky a écrit :

Quelqu'un aurait-il une idée ?


Moi, quand je fais un "listen", je demande quand-même "1" connexion possible et non "0". Mais cela ne vient peut-être pas de là...
Ecris un client en C et regarde si le problème se reproduit...


Message édité par Sve@r le 12-02-2006 à 19:41:37

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 12-02-2006 à 20:29:48    

J'ai testé avec un 1, mais, cela ne change rien. Il me semble que le zéro signifie que l'on peut accepter autant de connexions que l'on souhaite.
Il faudrait en effet que je teste un client en C...  
SInon, pour info, je code sous windows avec Dev-C++.
Ce qui est très bizzare, c'est que recv() ne reçoit pas de code d'erreur, il est vraiment toujours en attente de données alors que mon code php s'égosille à lui en envoyer et me dit lui aussi que la connexion est toujours établie. Comme si le recv() en avait marre d'attendre et décidait  de ne plus rien recevoir au bout de 15 secondes d'incativité.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed