socket_close() срабатывает только через 2 минуту

borzih2

Новичок
socket_close() срабатывает только через 2 минуту

В демоне чата используется socket_close(), но она срабатывает только через 2-3 минуты. Т.е. сокет продолжает висеть. На странице http://ru2.php.net/manual/ru/function.socket-close.php есть совет использовать такой код:
PHP:
    $arrOpt = array('l_onoff' => 1, 'l_linger' => 1);
    socket_set_block($this->Socket);
    socket_set_option($this->Socket, SOL_SOCKET, SO_LINGER, $arrOpt);
    socket_close($this->Socket);
но он тоже не помог. Можно ли моментально умертвить ненужный сокет?
 

borzih2

Новичок
Странно, но даже и так сокеты не закрываются.

Открываю основной сокет, который слушает порт, так:
PHP:
$sock = socket_create(AF_INET, SOCK_STREAM, 0) or die("Error");
socket_bind($sock, HOST, PORT)                 or die("Error");
socket_listen($sock, 20)                       or die("Error");
socket_set_nonblock($sock)                     or die("Error");
Дочерние сокеты, которые обрабатывают клиентов, открываю так:
PHP:
if(($msgsock = @socket_accept($sock))) { 
   socket_set_nonblock($msgsock); 
   $pool[] = & new phpServerThread($msgsock); 
   echo "New client is connected! Number of clients: ".count($pool)."\n";
}
где phpServerThread - класс, обслуживающий работу с клиентами; $poоl - массив, хранящий обекты "phpServerThread".
Закрываю ВСЕ сокеты так:
PHP:
  if(/*некое условие*/) {
    foreach($pool as $key => $client) { 
      $pool[$key]->destroy();
    }
    socket_shutdown($sock);
    socket_close($sock);
    die();
  }
где функция destroy() класса phpServerThread выглядит так:
PHP:
    function destroy() { 
      socket_shutdown($this->socket);
      socket_close($this->socket); 
    }
Но сокеты всё равно не закрываеются. Если после остановки демона чата его снова запустить, появляется ошибка:
Warning: socket_bind(): unable to bind address [48]: Address already in use in /usr/local/......../chat_server.php on line 69
Но если минут через 5 повторить попытку, но скорее всего запустится.

Чего не хватает в коде, чтобы на 100% умертвить все открытые сокеты?
 

borzih2

Новичок
Автор оригинала: Макс
насколько я помню, через SO_REUSEADDR решается
Отлично! SO_REUSEADDR проблему решило:

PHP:
$sock = socket_create(AF_INET, SOCK_STREAM, 0) or die("Error");
socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1) or die("Error");
socket_bind($sock, HOST, PORT)                 or die("Error");
socket_listen($sock, 20)                       or die("Error");
socket_set_nonblock($sock)                     or die("Error");
 

philimon

Новичок
Хм, но у меня почему-то это не работает:

$sockets[$i] = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($sockets[$i], SOL_SOCKET, SO_REUSEADDR, 1);
socket_set_nonblock($sockets[$i]);
@socket_connect($sockets[$i], $host, $port);

Причем, около 10 первых сокетов закрывается быстро, а дальше нужно ждать около 700000 микросекунд, чтобы дождаться закрытия.
p.s. Делаю в винде.
 

FractalizeR

Новичок
Автор оригинала: philimon
Причем, около 10 первых сокетов закрывается быстро, а дальше нужно ждать около 700000 микросекунд, чтобы дождаться закрытия.
p.s. Делаю в винде.
Именно 10 сокетов? Подключения производятся к Windows XP машине? tcpip.sys не пропатчен? Windows XP по умолчанию разрешает открывать только 10 входящих коннектов.
http://www.lvllord.de/?url=tools

Хотя, конечно, странно, что зависание именно на закрытии сокета.
 

philimon

Новичок
Автор оригинала: FractalizeR
Именно 10 сокетов? Подключения производятся к Windows XP машине? tcpip.sys не пропатчен? Windows XP по умолчанию разрешает открывать только 10 входящих коннектов.
Нет, после 15 соединений, хотя я одновременно запускаю 5 сокетов, так что может быть и после 16, и 17..
Сканирую подсеть в локалке на наличие ftp, так что к какой машине подключаюсь не знаю.
tcpip.sys лично я не патчил. Как его пропатчить?

Скрипт создает только 1 входящее соединение на чужой машине, наверное, проблема не в 10 коннектах
 

philimon

Новичок
Уж не знаю что изменилось, но использовав этот патч все заработало!!

Большое спасибо!
 
Сверху