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

Langage PHP Discussion :

[Système] Problème socket : script


Sujet :

Langage PHP

  1. #1
    Membre confirmé
    Inscrit en
    Juillet 2002
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 99
    Par défaut [Système] Problème socket : script
    Bonjour,

    J'essaie toujours de comprendre les sockets mais ça rentre doucement.

    J'ai essayé d'écrire une petit script pour mettre en pratique mles premieres connaissances mais j'ai encore un petit bug que je n'arrive vraiment pas à résoudre.

    Le script est lancé avec par SSH, l'objectif est d'afficher dans la fenetre des navigateurs, l'heure à laquelle la dernière personne s'est connecté à la socket.

    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
     
    $address='195.195.195.195';
    $port=7235;
    $clients = array();
    $socket = socket_create(AF_INET, SOCK_STREAM, 0);
    socket_bind($socket, $address, $port);
    socket_listen($socket);
    while(true) {
         //Le code se bloque jusqu'à ce qu'une nouvelle connexion cliente est établie
         $client = socket_accept($socket);
         //Lors d'une connexion, le code reprend ici, il est temps de lire ce qu'on nous envoie
         array_push($clients, $client);
         $param = socket_read($client,2300);
         foreach ($clients as $key => $value) {
              if ( is_resource($value) ) {
                   $msg = '<script type="text/javascript">document.write(\''.date('H:i:s').'\');</script>';
                   socket_write($value, $msg, strlen($msg));
              }
         }
         //socket_close($client);
    }
    Ensuite je lance un navigateur et je tape l'adresse :
    http://195.195.195.195:7235

    Mais la page tourne dans le vide sans renvoyer aucun résultat jusqu'a ce que j'arrete le script.

    D'où vient mon erreur ?

    Merci pour votre aide

  2. #2
    Expert confirmé
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Par défaut
    Salut !

    Je ne comprends pas pourquoi tu fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
                   $msg = '<script type="text/javascript">document.write(\''.date('H:i:s').'\');</script>';
    plutôt que simplement enfin...

    Je ne vois pas non plus très bien à quoi te sert le socket_read...

    ensuite, étant donné que tu réponds à un navigateur, il faut respecter le protocole HTTP...

    enfin, le socket_bind avec un adresse spécifique n'acceptera que les connection venant de cette adresse, pour accepter tout, il faut utiilser 0.0.0.0

    ton script devrait devenir :
    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
    $reponse = 'HTTP/1.1 200 OK'."\r\n".'Content-type: text/plain'."\r\n\r\n";
    $port=7235;
    $clients = array();
    $socket = socket_create(AF_INET, SOCK_STREAM, 0);
    socket_bind($socket, '0.0.0.0', $port);
    socket_listen($socket);
    while(true) {
         //Le code se bloque jusqu'à ce qu'une nouvelle connexion cliente est établie
         $client = socket_accept($socket);
         //Lors d'une connexion, le code reprend ici, il est temps de lire ce qu'on nous envoie
         array_push($clients, $client);
         $param = socket_read($client,2300);
         socket_write($value, $reponse, strlen($reponse));
         foreach ($clients as $key => $value) {
              if ( is_resource($value) ) {
                   $msg = '<script type="text/javascript">document.write(\''.date('H:i:s').'\');</script>';
                   socket_write($value, $msg, strlen($msg));
              } else unset($clients[$key]); //on retire le socket du tableau s'il n'est plus valide
         }
         //socket_close($client);
    }
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag :resolu: (en bas)

  3. #3
    Membre confirmé
    Inscrit en
    Juillet 2002
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 99
    Par défaut
    Merci pour ta réponse,

    Je comprends pas tout donc il y a des incohérences dans le script c'est sur.

    Snin j'ai essayé ton script j'ai toujours le même problème le navigateur mouline dans le vide et n'affiche l'heure que quand j'arrive le script.

    Je sais absolument pas pourquoi.

    Sous SSH j'ai ce message d'erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Warning: socket_write() unable to write to socket [104]: Connection reset by peer in /home/web/mysite/socket.php on line 17

  4. #4
    Expert confirmé
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Par défaut
    tu pourrais héberger le script sur une machine où on puisse y accèder en public, de manière à pouvoir le tester avec telnet
    (ou test le toi-même avec telnet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    telnet 195.195.195.195 7235
    )

    pour voir ce qu'il te répond, en théorie, ça devrait être
    HTTP/1.1 200 OK
    Content-type: text/plain

    H:i:s
    et si tu ouvres un second telnet (sans refermer le premier), tu devrais voir apparaître la seconde heure dans le premier...
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag :resolu: (en bas)

  5. #5
    Membre confirmé
    Inscrit en
    Juillet 2002
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 99
    Par défaut
    Oui avec telnet aucun problème à chaque nouvelle execution de telnet, les autres fenetres sont mise à jour.

    Par contre ça mouline sous IE.

  6. #6
    Expert confirmé
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Par défaut
    IE doit avoir un petit problème de buffer, le buffer est trop grand pour le message, essaie d'envoyer un message plus grand que simplement l'heure (une centaine de caractères par exemple)
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag :resolu: (en bas)

  7. #7
    Membre confirmé
    Inscrit en
    Juillet 2002
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 99
    Par défaut
    C'ext exactement ça

    Merci beaucoup pour ton aide swoög.

  8. #8
    Expert confirmé
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Par défaut
    De rien

    Bonne continuation, et bon courage pour les sockets... ^^

    oublie pas telnet, il permet d'y accèder en brut, c'est le mieux pour les tests ^^
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag :resolu: (en bas)

  9. #9
    Membre confirmé
    Inscrit en
    Juillet 2002
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 99
    Par défaut
    Bonjour,

    Je reviens avec mon script, j'arrive à présent à afficher l'heure qui se réactualise toute les secondes . Belle perf pour moi, les sockets ça commence à rentrer.

    Par contre j'ai un petit souci que je n'arrive pas à résoudre :

    Lorsque j'arrête le fichier qui envoi l'heure aux clients, les clients se retrouvent avec un joli "The page cannot be displayed".

    Est il possible de laisser afficher la page comme elle était avant la coupure, dans le cas présent, l'heure à laquelle le script a été arrété ?

    Je pense eventuellement a une redirection vers une autre page mais je n'arrive pas à saisir comment envoyer cette information au client.

    Merci pour votre aide.

  10. #10
    Membre confirmé
    Inscrit en
    Juillet 2002
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 99
    Par défaut
    Encore un truc que je pige pas, ce script affiche l'heure sans problème à tous les clients :
    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
     
    $address='195.195.195.195';
    $port=7235;
    $clients = array();
    $socket = socket_create(AF_INET, SOCK_STREAM, 0);
    socket_bind($socket, $address, $port);
    socket_listen($socket);
    socket_set_nonblock($socket); // Evite le blocage sur le socket_accept ?
    while(true) {
         $client = socket_accept($socket);
         array_push($clients, $client);
         foreach ($clients as $key => $value) {
              if ( is_resource($value) ) {
                   $msg = date('H:i:s');
                   socket_write($value, $msg, strlen($msg));
              }
         }
         sleep(1);
    }
    Cependant j'ai un petit problème de compréhension.
    Je ne comprends pas le fonctionnement de socket_accept().
    Cette fonction regarde si un client s'est connecté depuis le dernier appel de cette fonction ?
    Admettons que 2 clients se connectent pendant une itération de la boucle while, comme puis je connaitre ces 2 clients ?
    Que se passe t il si je mets le socket_accept avec le while ?

    Merci pour votre aide

  11. #11
    Expert confirmé
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Par défaut
    le client accepte permet d'accepter une connexion au socket écoutant, et de la traiter...

    normalement, tu ne peux traiter les connexions qu'une par une (premier arrivé, premier servi)

    j'ignore ce qu'il se passera si tu le mets dans la condition du while... sûrement pas grand chose

    pour ce qui est de l'arrêt du script, je pense que c'est parce que ton socket n'est pas correctement fermé...

    il faudrait un moyen de savoir quand le script doit être arretté (par exemple, lire une valeur dans un fichier à chaque itération du while, quand la valeur atteint 0, on ferme tous les sockets et on fait un exit...
    ou d'autres trucs de ce genre là...

    tu peux aussi ouvrir un second socket (sur un autre port) qui provoquera l'arrêt du script quand il détectera une connexion... dans ce cas, il te faudra utiliser des socket non bloquants pour pouvoir surveiller les deux sockets en même temps http://fr.php.net/manual/fr/function.socket-accept.php http://fr.php.net/manual/fr/function...t-nonblock.php
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag :resolu: (en bas)

  12. #12
    Membre confirmé
    Inscrit en
    Juillet 2002
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 99
    Par défaut
    Merci swoög pour cette réponse, cependant je butte toujours sur un problème.

    (Je voulais dire "avant" la boucle while )

    J'ai ajouté au début de la boucle le code suivant et j'ai mis un sleep(5) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    // Traite tous les nouveaux clients
     do {
         $client = socket_accept($socket);
         if ( is_resource($client) ) {
            echo "Nouveau client à ".date('H:i:s')." : ".$client."\r\n";
            array_push($clients, $client);
            socket_write($client, $reponse, strlen($reponse));
        }
     } while ( is_resource($client) );
    Mais il ne traite qu'un seul client à la fois.
    Par exemple une fois arrivé au sleep(5), je connecte 3 clients avant qu'il ne recommence la boucle.
    Mais il n'en traite qu'un seul avant de retomber sur le sleep(5).

    Je comprends pas où se trouve les autres, cela signifie t il que le 3eme client doit attentre 15s avant de pouvoir se connecter ?

  13. #13
    Expert confirmé
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Par défaut
    oui, c'est le principe de socket_accept, il accepte les clients un à un... en fait, si ton socket est bloquant, tu n'as pas besoin de sleep :
    ton script traitera toutes les connections à la file, et s'il n'y en a pas, il attendra
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag :resolu: (en bas)

  14. #14
    Membre confirmé
    Inscrit en
    Juillet 2002
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 99
    Par défaut
    Réponse éclair

    Le problème c'est que le traitement du script ne doit pas s'arreter si il n'y a plus de client.

    Mais je comprends pas ce qui marche pas dans ma boucle.
    Normalement, une fois qu'un client arrive, il le recupere dans $client, il fait le traitement dans la boucle, quand il arrive au while le $client est bien une ressource donc il recommence et devrait récuperer le 2eme client non ? C'est ça que je saisi pas, il est où le 2ème client puisqu'il ne le voit pas ?

  15. #15
    Expert confirmé
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Par défaut
    avec la boucle que tu avais au début (while(true)) il ne s'arrettait pas quand tu n'avais plus de client...

    et pour ta réponse, tu ne récupères les connections entrantes sur un socket en écoute qu'en faisant socket_accept, et qu'une par une...

    en attendant, elles sont en attentes, dans la pile TCP/IP du système (ou tout autre système de régulation des socket entrantes, je ne sais pas précisément comment ça fonctionne)
    socket_accept mais le script en attente de la prochaine connection s'il n'y en a pas... mais elle n'arrete pas le script...
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag :resolu: (en bas)

  16. #16
    Membre confirmé
    Inscrit en
    Juillet 2002
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 99
    Par défaut
    Je comprends, mais pourtant je fais une boucle et je repete autant de socket_accept qu'il y a de client en attente, et pourtant lors de la 2eme iteration, il ne trouve pas le 2eme client .

    Bon apparament, j'ai rajouté un sleep(3) dans la boucle et la surprise il trouve bien le deuxieme client en attente.

    Donc j'ai l'impression que le traitement de la file d'attente demande un temps assez long et que la boucle while va trop vite, quand la boucle recherche le client suivant, php n'a pas encore eu le temps de mettre le client en attente en tete de file. Ce qui expliquerait pourquoi il ne trouve pas le 2eme client. Bon ca c'est mon interpretation

  17. #17
    Membre confirmé
    Inscrit en
    Juillet 2002
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 99
    Par défaut
    Bonjour,

    J'ai une nouvelle question sur les sockets, décidement vraiment compliqué.

    J'ai donc ma page HTML avec une iframe du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
       <iframe src="http://www.domain.com:7459" width="300" height="300"></iframe>
    Mais par exemple lorsque je clique sur un lien (qui se trouve sur la page HTML et pas dans l'iframe) qui ouvre une fenetre popup l'iframe s'arrete et ne recois plus de données ? Je vois pas le rapport entre ces 2 actions.

    Merci pour votre aide

  18. #18
    Expert confirmé
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Par défaut
    Cela est entièrement géré par le client et ne dépend pas de toi...

    au pire, tu peux toujours en profiter pour lancer un reload() de l'iframe
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag :resolu: (en bas)

  19. #19
    Membre confirmé
    Inscrit en
    Juillet 2002
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 99
    Par défaut
    Swoög mon sauveur

    J'ai vais tester le reload, sinon ça ne bloque l'firame qu'avec IE, avec FF no problem. J'aime pas trop les pansements de ce genre mais bon si y'a que ça.

  20. #20
    Expert confirmé
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Par défaut
    Citation Envoyé par Gwipi
    sinon ça ne bloque l'firame qu'avec IE, avec FF no problem
    /me a bien envie de troller, lol

    pour éviter les comportement louches, tu peux détécter si tu es bien sous IE
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if(navigator.userAgent.indexOf("MSIE") != -1) /* reload */ ;
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag :resolu: (en bas)

Discussions similaires

  1. Réponses: 1
    Dernier message: 12/03/2007, 19h56
  2. Réponses: 1
    Dernier message: 13/09/2006, 16h10
  3. [DOS] Problème de script bat
    Par Philzegore dans le forum Windows
    Réponses: 3
    Dernier message: 04/04/2005, 12h35
  4. [Réseau] Problème socket
    Par neenee dans le forum Entrée/Sortie
    Réponses: 14
    Dernier message: 18/01/2005, 15h26
  5. [Système] Lancer un script Perl
    Par ebaynaud dans le forum API standards et tierces
    Réponses: 2
    Dernier message: 14/10/2004, 14h54

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