Résolu Serveur Socket. Si 1 user envoie des data ça déconnecte l'autre !!!

  • Auteur de la discussion benoit5699
  • Date de début

benoit5699

Nouveau membre
Bonjour à tous,

Je suis train de désespérer. Voilà, je mets au point un petit script php avec des sockets multi-users. Pour l'instant rien de terrible. En gros pour l'instant dès que le joueur 1 dit "coucou", je veux que tous les autres reçoivent "coucou"...une sorte de chat en somme...

Bon j'ai récupéré le code php qui suit, mais j'ai un bug étrange à savoir que j'arrive très bien à connecter plusieurs utilisateur mais dès que l'un envoie des données, ça déconnecte les autres...

Avez vous une idée d'où ça vient ? Je vous couvrirais d'or ou de bisous (au choix ;-) )

Merci de votre attention !

Benoît

Code:
<?php

// Set time limit to indefinite execution
set_time_limit (0);

// Set the ip and port we will listen on
$address = '127.0.0.1';
$port = 2010;
$max_clients = 10;

// Array that will hold client information
$client = Array();

// Create a TCP Stream socket
$sock = socket_create(AF_INET, SOCK_STREAM, 0);
// Bind the socket to an address/port
socket_bind($sock, $address, $port) or die('Could not bind to address');
// Start listening for connections
socket_listen($sock);

// Loop continuously
while (true) {
    // Setup clients listen socket for reading
    $read[0] = $sock;
    for ($i = 0; $i < $max_clients; $i++)
    {
        if ($client[$i]['sock']  != null)
            $read[$i + 1] = $client[$i]['sock'] ;
    }
    // Set up a blocking call to socket_select()
    $ready = socket_select($read, $write = NULL, $except = NULL, $tv_sec = NULL);
    /* if a new connection is being made add it to the client array */
    if (in_array($sock, $read)) {
        for ($i = 0; $i < $max_clients; $i++)
        {
            if ($client[$i]['sock'] == null) {
                $client[$i]['sock'] = socket_accept($sock);
                break;
            }
            elseif ($i == $max_clients - 1)
                print ("too many clients");
        }
        if (--$ready <= 0)
            continue;
    } // end if in_array
    
    // If a client is trying to write - handle it now
    for ($i = 0; $i < $max_clients; $i++) // for each client
    {
        if (in_array($client[$i]['sock'] , $read))
        {
            $input = socket_read($client[$i]['sock'] , 1024);
            if ($input == null) {
                // Zero length string meaning disconnected
                unset($client[$i]);

            }
            $n = trim($input);
            if ($input == 'exit') {
                // requested disconnect
                socket_close($client[$i]['sock']);
            } elseif ($input) {
                // strip white spaces and write back to user
                $output = ereg_replace("[ \t\n\r]","",'<thenodemyData="utilisateur : "'.$i.' />').chr(0);
				    for ($j = 0; $j < $max_clients; $j++) // for each client
						{
						if ($client[$j]['sock']) 
							{
							socket_write($client[$j]['sock'], $output);
							}
						}
            }
        } else {
            // Close the socket
            socket_close($client[$i]['sock']);
            unset($client[$i]);
        }
    }
} // end while
// Close the master sockets

socket_close($sock);

?>
 

benoit5699

Nouveau membre
 

batchy

Grand Maître
Meilleure réponse
Je vois pas ou c'est "étrange", ton code fait exactement ce que tu lui demande. Je te le résume :

Code:
- Initialise le bordel
- Crée un tableau qui contiendra tout les sockets connéctés.
- Crée un socket s1 qui écoute
- Tant que Vrai :
  - Construit un tableau contenant s1 et tout les autres sockets ouverts
  - Appelle select(), qui va attendre que l'un (ou plusieurs) des sockets du tableau ai des données reçues en attente. select() renvoie le nombre de sockets qui ont des données en attente.
  - si s1 à des données en attentes (aka, des connexions en attente), alors accepte les connexion, et met les dans le tableau. S'il n'y a que s1 qui a des données en attente, alors saute la suite.
  - pour tout les autres sockets :
      - S'il contient des données en attente :
          - Lit les données. Si ce qui est lu est une fin de connexion, alors ferme la connexion et supprime la du tableau. Sinon, pour tout les autres sockets :
             - Écrit cette donnée dans leur socket
     - Sinon (sous entendu : s'il ne contient pas des données en attentes) :
          - !!! Ferme la connexion !!!
ça veut dire que dès que tu reçoit quelque chose, tu va fermer tout ceux qui n'ont rien envoyé, c'est pas très sympa ;) Si tu vire le code (vers les lignes 74) qui ferme la socket s'il y a rien en attente, alors ça devrai mieux marcher ;)
 

benoit5699

Nouveau membre
Putain E-NORM-E-MENT merci pour cette réponse précise.
Bah en effet une fois que l'on a vu l'erreur c'est évident...mais comme j'avais récupéré ce bout de code et que je débute avec les sockets, c'est pas évident.
Merci encore et bonne continuation !!
++
BEnoît
 
Vous devez vous inscrire ou vous connecter pour répondre ici.
Derniers messages publiés
Statistiques globales
Discussions
730 079
Messages
6 716 702
Membres
1 586 247
Dernier membre
MrAzgarIII
Partager cette page
Haut