CLIENT / SERVEUR : LES SOCKETS

Afyn Messages postés 608 Date d'inscription samedi 3 août 2002 Statut Membre Dernière intervention 22 décembre 2016 - 27 avril 2011 à 19:40
katsankat Messages postés 571 Date d'inscription vendredi 30 décembre 2005 Statut Membre Dernière intervention 12 juillet 2012 - 27 mai 2012 à 09:06
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/53099-client-serveur-les-sockets

katsankat Messages postés 571 Date d'inscription vendredi 30 décembre 2005 Statut Membre Dernière intervention 12 juillet 2012 3
27 mai 2012 à 09:06
en PHP il n'y a pas de threads mais apparemment il existe un autre modèle d'I/O : select() qui permet de gérer plusieurs sockets sans bloquer sur read ou write. Select() est un appel système très puissant permettant le multiplexages d'entrées/sorties asynchrones. En C c'est un régal.
Morphinof Messages postés 255 Date d'inscription vendredi 20 avril 2007 Statut Membre Dernière intervention 9 août 2013 4
2 mai 2011 à 19:26
Oui seulement il n'y a pas de gestion native des thread en PhP :(

Par contre on peu utiliser pcntl_fork puis créer une thread pool mais ca aurai rendu la source trop complexe, mon but c'est de laisser implémenter le comportement:)
Gigatrappeur Messages postés 226 Date d'inscription lundi 6 mai 2013 Statut Membre Dernière intervention 3 juillet 2014 1
2 mai 2011 à 19:11
Code intéressant !

petite remarque :
la méthode loop de ton client : tu fais un appel récursif sur $this->loop
le problème est que lorsque tu fais un appel récursif, il empile sur le tas tes appels les un après les autres.
Et à un moment donné, ta mémoire sera pleine --> et crack !

il vaut mieux utiliser une boucle while...

public function loop()
{
while ($this->continue)
{
...

$this->listen();

...
}
}

autre remarque :
généralement, sur ce genre de code (qui existe plus en java), on utilise des threads.

Cordialement,
Gigatrappeur
Morphinof Messages postés 255 Date d'inscription vendredi 20 avril 2007 Statut Membre Dernière intervention 9 août 2013 4
28 avril 2011 à 15:53
Ahh peu être que ton hébergeur bloque l'ouverture de on port alors non ?

Moi je teste en local alors forcement ca marche mais je suis pas sur que tu puisse ouvrir une socket serveur sur n'importe quel port chez un hébergeur classique enfin c'est une idée ^^
Afyn Messages postés 608 Date d'inscription samedi 3 août 2002 Statut Membre Dernière intervention 22 décembre 2016
28 avril 2011 à 15:49
Je teste sur un hébergement, pas en local.
Donc pas de Cygwin pour moi.
Mais bon on va trouver ... je suis confiant ^^
Morphinof Messages postés 255 Date d'inscription vendredi 20 avril 2007 Statut Membre Dernière intervention 9 août 2013 4
28 avril 2011 à 15:47
Normalement tout se ferme correctement soit par la fonction timeout soit en fermant le script, personnellement en utilisant Cygwin je n'ai pas eu ce genre de soucis alors je pense pas ^^
Afyn Messages postés 608 Date d'inscription samedi 3 août 2002 Statut Membre Dernière intervention 22 décembre 2016
28 avril 2011 à 15:41
Du coup je peux plus relancer le serveur.
Peut être qu'on ne ferme pas la socket proprement et que le port reste utilisé ?
Morphinof Messages postés 255 Date d'inscription vendredi 20 avril 2007 Statut Membre Dernière intervention 9 août 2013 4
28 avril 2011 à 15:40
Hum je viens juste de vérifier a priori si il n'arrive pas a lire ca génère un warning et on peu pas l'empêcher, pour éviter ca mets un @ devant socket_accept ca enlèvera ce warning et de toute façon ce qui nous intéresse c'est de tester l'état false, sinon ca viens pas de socket_set_nonblock que j'ai mit justement pour permettre des connections simultanées de plusieurs clients.
Afyn Messages postés 608 Date d'inscription samedi 3 août 2002 Statut Membre Dernière intervention 22 décembre 2016
28 avril 2011 à 15:21
Pour info ->

En supprimant nonblock j'ai toujours le même warning (toutes les 5 secondes)
Morphinof Messages postés 255 Date d'inscription vendredi 20 avril 2007 Statut Membre Dernière intervention 9 août 2013 4
28 avril 2011 à 15:14
Ah bizarre ca me fait pas ca chez moi, unable to accept incoming connection je dirait que soit ca viens du port que tu utilise soit ca viens peu être de ce bug : http://bugs.php.net/bug.php?id=29560 mais je suis pas sur a 100%, en tout cas au niveau de la structure c'est comme ca qu'il faut faire, tu peux essayer d'enlever le mode non bloquant des socket (socket_set_nonblock(self::$socket)) pour essayer de voir si ca change quelque chose.
Afyn Messages postés 608 Date d'inscription samedi 3 août 2002 Statut Membre Dernière intervention 22 décembre 2016
28 avril 2011 à 14:54
/*
* Boucle infinie du serveur, attente des connections
*/
public function loop()
{
if(($client = socket_accept(self::$socket)) !== false)
{
echo 'New client '.$client.' has connected'.BR;
self::$clients[] = $client;
}

$this->listen();

ob_flush();
usleep(SERVER_LOOP_SLEEP);

if ($this->continue)
$this->loop();
}

J'ai une erreur avec cette ligne : if(($client = socket_accept(self::$socket)) !== false)

même lorsque le serveur tourne seul (personnes de connecté)

Je vois ça dans le fichier error_log :
socket_accept() [['function.socket-accept function.socket-accept]]: unable to accept incoming connection [11]
Morphinof Messages postés 255 Date d'inscription vendredi 20 avril 2007 Statut Membre Dernière intervention 9 août 2013 4
28 avril 2011 à 14:29
Cette fonction réponds au client que si le client envoi un message comme suit : if (($datas = $this->read($client))) alors je reponds.

A priori ca devrai donc marcher, mais je n'ai pas pu tester avec plusieurs connections, est ce que le serveur te dit qu'il y a 2 connectés et si oui est ce que tes deux clients envoient bien un message au serveur ?
Afyn Messages postés 608 Date d'inscription samedi 3 août 2002 Statut Membre Dernière intervention 22 décembre 2016
28 avril 2011 à 13:49
Autre précision :

Quand on connecte plusieurs clients, la fonction listen semble ne pas renvoyer les datas à tous les clients connectés.

(J'ai plein de choses à apprendre avec cette source ... elle est vraiment super)
Morphinof Messages postés 255 Date d'inscription vendredi 20 avril 2007 Statut Membre Dernière intervention 9 août 2013 4
28 avril 2011 à 08:49
Hello !

Quand on lance le serveur celui ouvre une socket sur un port et écoutes toutes les connections client qui arrivent sur le dit port.
Le client lui ouvre une sockect qui se connecte via ce port au serveur.
Lorsqu'un client se connecte le serveur stocke ce client dans un tableau de client, le serveur envois régulièrement aussi un message "live" a sa liste pour retirer les clients déconnectes.

Voila ^^
Afyn Messages postés 608 Date d'inscription samedi 3 août 2002 Statut Membre Dernière intervention 22 décembre 2016
27 avril 2011 à 19:40
Bonjour

Ca semble fonctionner ^^
C'est possible d'avoir plus d'infos ? sur le fonctionnement !

Merci d'avance
Rejoignez-nous