Page 1 sur 1

socket_read question, probleme

Posté : 06 déc. 2012, 00:50
par dorian
Bonjour,

Je travaille sur un projet perso, et j'ai un souci au niveau de la gestion de socket en multi client.

d'aprés php.net, il est possible de passer a la fonction socket_read(), soit une socket créé par socket_create soit accepté par socket_accept.

Si je comprend bien, celle renvoyé par socket_create est la socket serveur, et celles renvoyés par socket_accept sont les socket client, est ça ?

Si oui sa m'arrangerai de mettre ma socket serveur en parametre de socket_read pour attendre que un client parmi plusieurs ecrive dans la socket.

Plus clairement, j'accepte 4 clients et attende que l'un d'entre eux ecrive, mais je ne peux pas mettre un une socket client precise dans socket_read vu que je sais pas qui va ecrire ...

Et quand je met la socket serveur sa plante...

Code : Tout sélectionner

if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) { echo "socket_create() a échoué : raison : " . socket_strerror(socket_last_error()) . "\n"; } if (socket_bind($sock, $this->address, $this->port) === false) { echo "socket_bind() a échoué : raison : " . socket_strerror(socket_last_error($sock)) . "\n"; } if (socket_listen($sock, 5) === false) { echo "socket_listen() a échoué : raison : " . socket_strerror(socket_last_error($sock)) . "\n"; } /*Accepte client */ for($i=0;$i<$this->maxClient;$i++){ if(($client = socket_accept($sock)) === false){ echo "socket_accept() a échoué : raison : " . socket_strerror(socket_last_error($sock)) . "\n"; break; }else echo "<br/>Client $client[$i] has connected\n"; /*on stock les clients(socket) dans un membre de l'objet joueur*/ $this->joueurs[$i] = new Joueur($client,$i); } while($start){ $messageClient = socket_read($sock , 1024);//PHP_NORMAL_READ /*suite .....*/

Re: socket_read question, probleme

Posté : 06 déc. 2012, 09:57
par xTG
Tu ne peux pas utiliser une seule socket pour 3 connexions en même temps.
Il faut la fermer entre deux et attendre la seconde connexion, ect.

Re: socket_read question, probleme

Posté : 06 déc. 2012, 13:42
par dorian
Euuh je suis pas sur d'avoir bien compris, mais l'acceptation des clients marche trés bien, c'est lors du read que sa plante !?

Re: socket_read question, probleme

Posté : 06 déc. 2012, 14:14
par xTG
Bah oui, tu réécrases une connexion à chaque fois.
Donc quand la socket reçois de force un message d'une adresse qui n'est pas celle qu'elle avait enregistré (la dernière) elle comprend plus trop ce qui lui arrive. ;)

si tu préfères le accept va stocker dans une structure l'adresse distante du client connecté.
Donc trois accept => une seule adresse => celle du dernier accept.
Réception d'un message en provenant du second client => socket = WTF ?

Re: socket_read question, probleme

Posté : 06 déc. 2012, 14:17
par dorian
que dois-je aire alors ? un socket_close($client) à la fin de ma boucle d'acceptation ? si c'est sa j'ai essayer vite fait sa n'a pas marché,

Je dois y aller je revien dans 2heures si tu est toujours la ...

ps : Merci de m"avoir répondu !

Re: socket_read question, probleme

Posté : 06 déc. 2012, 14:26
par xTG
Bah il te faudrait une socket pour chaque client => un array de socket.
$socket = array();
for( $i = 0; $i < $this->maxClient; $i++){
if (($sock[] = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
            echo "socket_create() a échoué : raison : " . socket_strerror(socket_last_error()) . "\n";
            exit(); // en cas d'erreur sur la création de socket il ne faut pas faire de bind et compagnie !
         }
 
         if (socket_bind($sock[$i], $this->address, $this->port) === false) {
            echo "socket_bind() a échoué : raison : " . socket_strerror(socket_last_error($sock[$i])) . "\n";
         }
 
         if (socket_listen($sock[$i], 5) === false) {
            echo "socket_listen() a échoué : raison : " . socket_strerror(socket_last_error($sock[$i])) . "\n";
         }
}

for($i=0;$i<$this->maxClient;$i++){
 
            if(($client = socket_accept($sock[$i])) === false){
                echo "socket_accept() a échoué : raison : " . socket_strerror(socket_last_error($sock[$i])) . "\n";
                break;
            }else echo "<br/>Client $client[$i] has connected\n";
 
            /*on stock les clients(socket) dans un membre de l'objet joueur*/
            $this->joueurs[$i] = new Joueur($client,$i);
         }

while($start){
    for($i=0;$i<$this->maxClient;$i++){
         $messageClient = socket_read($sock[$i] , 1024);//PHP_NORMAL_READ
          echo $messageClient;
    }
}
Je n'ai pas testé mais le principe est là.
Le mieux aurait été de faire un thread par socket client mais PHP n'est pas vraiment un langage fait pour cela...

Re: socket_read question, probleme

Posté : 06 déc. 2012, 18:22
par dorian
Hul merci,

Je vois le principe, c'est qu'on retrouve sur internet.

Ma premiere question est est ce que socket_read est bloquant ? si oui, il va y avoir un souci puisque n'importe quel clients peut ecrire a n'importe quel moment du coup php va attendre que le premier client ecrive alors qu'il peut ne jamais ecrire, a l'inverse le client suivant (dans la boucle) serai suscptible d'ecrire mais socket_read va attendre sur le premier client du tableau de socket qui peut comme je disait ne jamais ecrire !?

Je dois me forcement me tromper à un endroit...

D'aprés ce que je comprend je dois creer un socket "local" ou "serveur" pour chaque client ? enplus d'avoir une socket par client renvoyé socket_accept().

Dans mon cas je pensse que l'ideal serai que socket_read ne soit pas bloquant pour pouvoir lire toute les socket en permanence non ?

Merci

Re: socket_read question, probleme

Posté : 06 déc. 2012, 21:00
par Saian
Salut, pareil je suis à côté de la plaque mais il me semble bien que socket_read est une fonction bloquante dont le retour ne se fait que quand des données sont reçues ou que la connexion est interrompue.

A priori tu ne peux pas surveiller plusieurs socket à la fois dans un seul script php. Si tu ne peux pas le faire autrement qu'en php il faudrait exécuter un script par socket.

Re: socket_read question, probleme

Posté : 06 déc. 2012, 21:35
par dorian
mmmh c'est pas mal embattent sa ! personne n'a une autres alternative à proposer par hasard^^ ?

Re: socket_read question, probleme

Posté : 07 déc. 2012, 10:29
par xTG
Tu peux essayer avec socket_recv avec le flag MSG_DONTWAIT.
Ou bien voir de ce côté :
- pthreads (je viens de voir ça en cherchant les PCNTL, faudrait voir ce que c'est vraiment)
- PCNTL
Mais PHP n'est vraiment pas un langage fait pour faire tourner plusieurs tâches...