Проблема с сокетами

webmaster_Chris

Новичок
Имеем TCP сервер, на который подключается клиент из сети и сбрасывает данные.

PHP:
<?php
// PHP SOCKET SERVER
error_reporting(E_ERROR);
// Configuration variables
$host = "127.0.0.1";
$port = 4041;
$max = 20;
$client = array();

// No timeouts, flush content immediatly
set_time_limit(0);
ob_implicit_flush();

// Server functions
function rLog($msg){
             $msg = "[".date('Y-m-d H:i:s')."] ".$msg;
             print($msg."\n");

}
// Create socket
$sock = socket_create(AF_INET,SOCK_STREAM,0) or die("[".date('Y-m-d H:i:s')."] Could not create socket\n");
// Bind to socket
socket_bind($sock,$host,$port) or die("[".date('Y-m-d H:i:s')."] Could not bind to socket\n");
// Start listening
socket_listen($sock) or die("[".date('Y-m-d H:i:s')."] Could not set up socket listener\n");

rLog("Server started at ".$host.":".$port);
// Server loop
while(true){
             socket_set_block($sock);
             // Setup clients listen socket for reading
             $read[0] = $sock;
             for($i = 0;$i<$max;$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 clients array
             if(in_array($sock,$read)){
                          for($i = 0;$i<$max;$i++){
                                       if($client[$i]['sock']==null){
                                                    if(($client[$i]['sock'] = socket_accept($sock))<0){
                                                                 rLog("socket_accept() failed: ".socket_strerror($client[$i]['sock']));
                                                    }else{
                                                                 rLog("Client #".$i." connected");
                                                    }
                                                    break;
                                       }elseif($i == $max - 1){
                                                    rLog("Too many clients");
                                       }
                          }
                          if(--$ready <= 0)
                          continue;
             }
             for($i=0;$i<$max;$i++){
                          if(in_array($client[$i]['sock'],$read)){
                                       $input = socket_read($client[$i]['sock'],1024);
                                       if($input==null){
                                                    unset($client[$i]);
                                       }
                                       $n = trim($input);
                                       $com = split(" ",$n);

// И ВОТ ЗДЕСЬ НАЧИНАЕТСЯ ПРИКОЛ

написан обработчик простой, что если if($n=="DATAblalalala"){ }

и если вдруг 

if ($n == ""){
   socket_close($client[$i]['sock']);
   unset($client[$i]['sock']);
   rLog("Disconnected(2) client #".$i);
}

//////////////////////////////////////

                                       if($n=="EXIT"){
                                                    if($client[$i]['sock']!=null){
                                                                 // Disconnect requested
                                                                 socket_close($client[$i]['sock']);
                                                                 unset($client[$i]['sock']);
                                                                 rLog("Disconnected(2) client #".$i);
                                                                 for($p=0;$p<count($client);$p++){
                                                                              socket_write($client[$p]['sock'],"DISC ".$i.chr(0));
                                                                 }
                                                                 if($i == $adm){
                                                                              $adm = -1;
                                                                 }
                                                    }
                                       }elseif($n=="TERM"){
                                                    // Server termination requested
                                                    socket_close($sock);
                                                    rLog("Terminated server (requested by client #".$i.")");
                                                    exit();
                                       }elseif($input){
                                                    // Strip whitespaces and write back to user
                                                    // Respond to commands
                                                    /*$output = ereg_replace("[ \t\n\r]","",$input).chr(0);
                                                    socket_write($client[$i]['sock'],$output);*/
                                                    if($n=="PING"){
                                                                 socket_write($client[$i]['sock'],"PONG".chr(0));
                                                    }
                                                    if($n=="<policy-file-request/>"){
                                                                 rLog("Client #".$i." requested a policy file...");
                                                                 socket_write($client[$i]['sock'],$cdmp.chr(0));
                                                                 socket_close($client[$i]['sock']);
                                                                 unset($client[$i]);
                                                                 $cdmp="";
                                                    }
                                       }
                          }else{
                                       //if($client[$i]['sock']!=null){
                                                    // Close the socket
                                                    //socket_close($client[$i]['sock']);
                                                    //unset($client[$i]);
                                                    //rLog("Disconnected(1) client #".$i);
                                       //}
                          }
             }
}
// Close the master sockets
socket_close($sock);
?>
И вот наступает данный момент когда клиент присылает нулевую строку и рвет САМ связь, вперед чем сервер... После этого сервер начинает загружать на 100% CPU... и перестает принимать коннекты:

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Connection closed by foreign host.

При этом если зайти и самому написать exit, не прерывая соединение со своей стороны, то всё продолжает работать замечательно.

Подскажите как можно эту ситуацию победить... Гугл облазил, пока вариантов решения не нашел. Если 5.3 то ни на что не жалуется, если 5.4 жалуется на:
PHP:
$ready = socket_select($read,$write = NULL, $except = NULL, $tv_sec = NULL);
может сокет открытый не верно закрываю?.. но почему то до этого на 5.1 работал на ура... после перехода на 5.3 уже алес...
 

webmaster_Chris

Новичок
Ещё раз уточню, что проблема возникает, когда клиент подключается и обрывает соединение. Эмулировать очень просто, открывает два терминала, в одном набираем telnet 127.0.0.1 4041, переключаемся в другой и killall telminal... И получаем "привет"...
 
Сверху