Gestion des sockets

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Gestion des sockets

par Sékiltoyai » 23 avr. 2007, 22:51

Je vois que peu de monde a réagi à ce sujet, ce n'est pas bien grave, le sujet est réglé, je vous transmet mes scripts si ca vous intéresse :
<?php

// Script serveur

ob_implicit_flush();

echo 'Généré à ' . date('H:i', time()) . '<br /><br />';;

if( $com_serv = stream_socket_server( 'tcp://0.0.0.0:2041/') )
{

	while( !($com_sock = stream_socket_accept($com_serv)) ) {}
	
	$buf = 'Message transmis à ' . date('H:i:s', time());
	stream_socket_sendto($com_sock, $buf);
	echo 'Message transmis<br />';
	
	while(($buf = stream_socket_recvfrom($com_sock, 1024)) != '')
	{
		echo $buf;
	}
	fclose($com_sock);

}
fclose($com_serv);

?>
<?php

// Script client

ob_implicit_flush();

echo 'Généré à ' . date('H:i', time()) . '<br /><br />';

if( $com_cl = stream_socket_client('tcp://127.0.0.1:2041/') )
{

	while(($buf = stream_socket_recvfrom($com_cl, 1024)) != '')
	{
		echo $buf;
	}
	
	$buf = 'Réponse transmise à ' . date('H:i:s', time());
	stream_socket_sendto($com_cl, $buf);
	echo '<br />Réponse transmise';
	fclose($com_cl);

}

?>
Mon hypothèse est qu'il y a un problème avec certaines fonctions de flux ou de sockets et PHP est mal documenté à ce niveau. Je vous conseille l'utilisation des flux stream_socket_* par rapport aux sockets socket_* qui sont mal documentés et pas forcément très au point, et de fonctions plutôt "bas niveau" comme stream_socket_recvfrom et stream_socket_sendto qui sont plus adaptées aux flux que les fonctions de fichier fwrite et fread et qui vous permettront de contrôler directement votre connexion.
J'espère que mon problème servira à quelqu'un, pour ma part je pose avec plaisir le tag réglé, mais comme vous avez pu le remarquer, je reste dans le coin si certains ont besoin d'aide :)

Gestion des sockets

par Sékiltoyai » 22 avr. 2007, 15:31

Bonjour,

J'ai dernièrement installé un serveur de tests sur mon pc, (Server Version: Apache/2.2.4 (Win32) PHP/5.2.1), et je ne sais pas si je n'ai pas compris les sockets ou bien si ca vient du serveur, du firewall, de la facon dont windows gère les connexions TCP, ..., mais des scripts tous simples ne marchent pas.
Pour expliquer mon problème, ce que je teste en ce moment est une communication interscripts via des connexions tcp (c'est un peu lourd, mais si ca marche en tcp un jour, à mon avis je le recoderais ensuite en udp voire en un protocole moins lourd encore). J'ai donc deux scripts, un script qui joue le role de serveur dans la communication, et l'autre le role de client. Bref, j'ai testé pas mal de fois, avec des sockets bloquantes et non bloquantes (d'ailleurs, il n'y a pas beaucoup d'explications dans la doc, je crois juste avoir compris que pour les sockets non bloquantes, l'opération de lecture ne rend quelquechose que si un paquet a été reçu avant l'appel de cette opération, en tous cas c'est ce qui me parait le plus logique), et avec plusieurs fonctions de sockets (fonctions stream_socket_* ou socket_*).

Le résultat est que autant ces scripts marchent (bien entendu, le script serveur est lancé avant le script client):

serveur :
écoute (création du socket, bind, et listen)
acceptation de la connexion
envoi de message
fermeture de la connexion
client :
connexion (création du socket, bind, et connect)
réception et affichage du message ( while($buf = socket_read($com_cl, 1024)) { echo $buf; } )
fermeture de la connexion

ainsi que :

serveur :
écoute (création du socket, bind, et listen)
acceptation de la connexion
envoi de message
fermeture de la connexion
acceptation de la connexion
réception et affichage du message
fermeture de la connexion
client :
connexion (création du socket, bind, et connect)
réception et affichage du message ( while($buf = socket_read($com_cl, 1024)) { echo $buf; } )
fermeture de la connexion
connexion
envoi de message
fermeture de la connexion

mais par contre, et ce, même avec des sockets bloquantes, ces scripts ne marchent pas :

serveur :
écoute (création du socket, bind, et listen)
acceptation de la connexion
envoi de message
réception et affichage du message
fermeture de la connexion
client :
connexion (création du socket, bind, et connect)
réception et affichage du message ( while($buf = socket_read($com_cl, 1024)) { echo $buf; } )
envoi de message
fermeture de la connexion

(implémentation en annexe à la fin du post)

C'est à dire que j'ai l'impression que après la réception d'un message par le script client, ce dernier n'arrive pas à en envoyer un nouveau, ce qui se traduit par un blocage de l'éxécution avec des sockets bloquantes, ou l'ignorance de l'opération de lecture pour des sockets non bloquantes, et je n'ai pas le sentiment que ce soit normal car je n'ai jamais entendu dire que les connexions ne se faisaient que dans un sens, car beaucoup de scripts et exemples sur internet envoient une réponse juste après la réception d'un message sans se reconnecter.

Je ne demande pas forcément que vous ayez une réponse immédiate à mon problème, mais j'aimerais si c'est possible que vous m'enleviez quelques doutes, à savoir :
-Est ce que ma facon d'appréhender les sockets est correcte ?
-Est ce que vous savez si le comportement des sockets est correcte pour ma version de php ?
-Est ce que, de même le comportement des sockets est éprouvé pour les systèmes Win32 ?
-Est ce que vous avez une idée d'où pourrait venir mon problème ?
-Est ce que quelqu'un a une implémentation dont il est complètement sûr à me proposer pour effectuer ce test ?

Même si le sujet est plutôt technique, je vous remercie par avance de vos réponses (en espérant que je vous ai donné assez d'indications :D ).
S'il vous manque des indications sur la configuration d'apache ou d'autres logiciels de mon environnement, je peux parfaitement vous les fournir...


Annexe :

La dernière implémentation que j'ai fait du test est celle ci :

Code : Tout sélectionner

<?php // Script serveur ob_implicit_flush(); echo 'Généré à ' . date('H:i', time()) . '<br /><br />';; if( $com_serv = stream_socket_server( 'tcp://0.0.0.0:2041/') ) { while( !($com_sock = stream_socket_accept($com_serv)) ) {} fwrite($com_sock, 'Message transmis à ' . date('H:i:s', time()) ); echo 'Message transmis<br />'; while(!feof($com_sock)) { echo fgets($com_sock, 1024); } fclose($com_sock); } fclose($com_serv); ?>

Code : Tout sélectionner

<?php // Script client ob_implicit_flush(); echo 'Généré à ' . date('H:i', time()) . '<br /><br />'; if( $com_cl = stream_socket_client('tcp://127.0.0.1:2041/') ) { while(!feof($com_cl)) { echo fgets($com_cl, 1024); } $buf = 'Réponse transmise à ' . date('H:i:s', time()); fwrite($com_cl, $buf); echo '<br />Réponse transmise'; fclose($com_cl); } ?>