Erreur avec socket_bind php [Résolu]

Signaler
Messages postés
165
Date d'inscription
samedi 8 mai 2010
Statut
Membre
Dernière intervention
3 janvier 2015
-
Messages postés
1309
Date d'inscription
samedi 31 janvier 2009
Statut
Membre
Dernière intervention
5 juin 2013
-
Bonjour !


J'ai un problème avec socket_bind() :

dans un code de mini-chat je dois lancer un script dans lequel il y a un socket_bind le problème est que ça plante et affiche ce message pour la fonction socket bind :


Warning: socket_bind() [function.socket-bind]: unable to bind address [0]: Une seule utilisation de chaque adresse de socket (protocole/adresse réseau/port) est habituellement autorisée. in C:\Program Files\EasyPHP 3.0\www\serveur.php on line 27
Port déja utilise


savez vous en général ce qui peut empêcher socket_bind() de fonctionner ? Quelles sont les erreurs typiques avec cette fonction ?


mon script se présente comme ceci (c'est le script créé par azmeuk sur le SDZ dans le tuto sur les sockets en php) :


<?php
set_time_limit(0);

//On crée notre classe
class Chat_Server
{
var $socket=NULL;
var $client=NULL;

//Méthode qui démarre le serveur
function Start($adresse,$port)
{
echo"Lancement du serveur...\n";
$this->clients=array();

//Création de la socket
$this->socket = socket_create(AF_INET, SOCK_STREAM,SOL_TCP);
if($this->socket)
{

echo "creation de socket reussie !\n";

}

// socket_close($this->socket);
//on lie la ressource sur laquelle le serveur va écouter
socket_bind($this->socket, $adresse,$port) or die("Port déja utilise\n");
echo socket_last_error()."
";
echo socket_strerror(socket_last_error());

//socket_connect($this->socket, $adresse, $port) or die("Bug !\n");
//On prépare l'écoute
socket_listen($this->socket);
//Boucle infinie, car le serveur ne doit s'arrêter que si on lui demande
while(true)
{
//Le code se bloque jusqu'à ce qu'une nouvelle connexion client soit établie
$this->client = socket_accept($this->socket);
//Cette méthode lit les données reçues par un client, et les redistribue
$reception = socket_read($this->client , 255);
$pseudo = substr($reception , 0 , strpos($reception , ' '));
$message = substr($reception , strpos($reception , ' ')+1 , strlen($reception));
//Le message est "/connect", donc on stocke la socket dans le tableau
if($message == "/connect")
{
$this->clients[$pseudo]=$this->client;
echo "$pseudo connected\n";
}
//C'est donc un message : ici on va envoyer le message vers chacun des clients
else
{
echo "Pseudo: [".$pseudo."] Message recu: [".$message."] Message envoye a : ";
//On passe chaque case du tableau = chaque client, et on lui envoie le message
foreach( $this->clients as $nom_case => $socket_en_cours)
{
//Si ça ne marche pas, c'est qu'il est déconnecté
if(@socket_write($socket_en_cours, $reception, strlen($reception)) === false)
{
//La socket est enlevée du tableau
unset($this->clients[$nom_case]);
echo "[$nom_case s'est deconnecte]";
}
else
echo "$nom_case ";
}
//On ferme la socket qui vient de nous apporter un message
socket_close($this->client);
echo"\n";
flush();
}
}
}
}
$chat = new Chat_Server();
$chat->Start('192.168.x.x',35353);
?>



ma config :

J'utilise easyphp comme serveur en local que j'ai rendu accessible dans tout le reseau local via l'adresse ip du serveur.


Merci pour vos rep. !




@+!

;-)
A voir également:

5 réponses

Messages postés
1309
Date d'inscription
samedi 31 janvier 2009
Statut
Membre
Dernière intervention
5 juin 2013
12
tu dis que le problème est la fermeture de la socket... alors que si tu regardes il y a bien à la fin "socket_close($this->client);"

Ce socket_close() concerne uniquement la fermeture de la socket d'un client, pas celle du serveur ($this->socket);

Aurais tu un script qui fait la même chose pour expliciter l'utilisation de la fonction socket_bind ?

Pas sous la main non, mais tu trouveras sans doute ton bonheur .
Messages postés
165
Date d'inscription
samedi 8 mai 2010
Statut
Membre
Dernière intervention
3 janvier 2015

je precise que j'ai verifié le port que j'utilise et il n'est urilisé par aucun protocol
et n'est pas sensé être utilisé par easyphp, comment vérifier ce point ?

;-)
Messages postés
165
Date d'inscription
samedi 8 mai 2010
Statut
Membre
Dernière intervention
3 janvier 2015

Comme ça c'est peut être mieux



<?php
set_time_limit(0);

//On crée notre classe
class Chat_Server
{
var $socket=NULL;
var $client=NULL;

//Méthode qui démarre le serveur
function Start($adresse,$port)
{
echo"Lancement du serveur...\n";
$this->clients=array();

//Création de la socket
$this->socket = socket_create(AF_INET, SOCK_STREAM,SOL_TCP);
if($this->socket)
{

echo "creation de socket reussie !\n";

}

// socket_close($this->socket);
//on lie la ressource sur laquelle le serveur va écouter
socket_bind($this->socket, $adresse,$port) or die("Port déja utilise\n");
echo socket_last_error()."
";
echo socket_strerror(socket_last_error());

//socket_connect($this->socket, $adresse, $port) or die("Bug !\n");
//On prépare l'écoute
socket_listen($this->socket);
//Boucle infinie, car le serveur ne doit s'arrêter que si on lui demande
while(true)
{
//Le code se bloque jusqu'à ce qu'une nouvelle connexion client soit établie
$this->client = socket_accept($this->socket);
//Cette méthode lit les données reçues par un client, et les redistribue
$reception = socket_read($this->client , 255);
$pseudo = substr($reception , 0 , strpos($reception , ' '));
$message = substr($reception , strpos($reception , ' ')+1 , strlen($reception));
//Le message est "/connect", donc on stocke la socket dans le tableau
if($message == "/connect")
{
$this->clients[$pseudo]=$this->client;
echo "$pseudo connected\n";
}
//C'est donc un message : ici on va envoyer le message vers chacun des clients
else
{
echo "Pseudo: [".$pseudo."] Message recu: [".$message."] Message envoye a : ";
//On passe chaque case du tableau = chaque client, et on lui envoie le message
foreach( $this->clients as $nom_case => $socket_en_cours)
{
//Si ça ne marche pas, c'est qu'il est déconnecté
if(@socket_write($socket_en_cours, $reception, strlen($reception)) === false)
{
//La socket est enlevée du tableau
unset($this->clients[$nom_case]);
echo "[$nom_case s'est deconnecte]";
}
else
echo "$nom_case ";
}
//On ferme la socket qui vient de nous apporter un message
socket_close($this->client);
echo"\n";
flush();
}
}
}
}
$chat = new Chat_Server();
$chat->Start('192.168.x.x',35353);
?>



;-)
Messages postés
1309
Date d'inscription
samedi 31 janvier 2009
Statut
Membre
Dernière intervention
5 juin 2013
12
Salut,

Autant être franc : c'est du code très brouillon bourré d'erreurs de conceptions. Voici ce que j'ai réussi à dégager du tas (il doit y avoir d'autres trucs à excaver) :
- Très mauvaise utilisation de la programmation orientée objet, si c'est pour continuer à faire une énorme méthode unique qui contient tout le code de ton programme autant ne pas utiliser d'objets.
- Gestion des erreurs tout aussi mauvaises. Je ne prendrai comme exemple que le socket_create() : si la fonction réussie tu affiche un message et en cas d'échec tu continue ton code comme un gros boulet.
- Mais bon sang c'est quoi ces socket_accept() et socket_read() à chaque tour de boucle ? Pourquoi il n'y a pas de socket_select() pour savoir sur quelle socket lire ou accepter une connexion ?
- Et la socket du serveur tu la ferme où ? Ton soucis viens semble-t-il de là, à quitter le programme sans fermer proprement la socket cette dernière ne doit pas disparaitre avant un certains temps, laissant le port utilisé.
Messages postés
165
Date d'inscription
samedi 8 mai 2010
Statut
Membre
Dernière intervention
3 janvier 2015

Peux tu être plus explicite ?
tu dis que le problème est la fermeture de la socket... alors que si tu regardes il y a bien à la fin "socket_close($this->client);"

C'est vrai que le code n'est pas terrible (c pas le mien ) j'ai trouvé un autre bout de code qui fait la même chose et qui a l'air de mieux fonctionner.



ce code était sensé réaliser un mini serveur de chat attendant des connect , read write sur ses sockets. Aurais tu un script qui fait la même chose pour expliciter l'utilisation de la fonction socket_bind ?

Merci



;-)