Как узнать всякий раз, когда соединение сбрасывается в одноранговой сети в php? - PullRequest
8 голосов
/ 31 марта 2012

В последнее время я работаю над созданием TCP-сервера с использованием PHP (для начала я знаю неправильный выбор, но это рабочий стандарт), поэтому я достиг точки, когда есть надежный прототип для его тестирования, и онпоказал хорошие результаты.при запуске я использовал функции сокетов для обработки соединения с сервером, и это работало хорошо, но одна из главных целей проекта - сделать канал защищенным, чтобы я переключился на stream_socket.

что я хочу, так это socket_last_errorэквивалент в группе stream_socket, поэтому я могу знать, когда соединение с клиентом закрыто или нет.в текущей ситуации все процессы будут ждать, пока таймер таймаута отпустится, даже если клиент уже закрыт.

Я искал в сети и обнаружил, что нет способа выяснить это через PHP, и я обнаружил, чтонекоторые люди открывали тикет об этом, запрашивая эквивалент socket_last_error для stream.https://bugs.php.net/bug.php?id=34380

так есть ли вообще знать, когда сигнал FIN_WAIT повышается или нет?

Спасибо,

1 Ответ

1 голос
/ 31 марта 2012

Не думаю, что это возможно для семьи stream_socket, похоже, это слишком высокий уровень.

Я пытался сделать очень хакерское решение, я не знаю, будет ли оно работать для вас, оно не очень надежно:

<?php
set_error_handler('my_error_handler');

function my_error_handler($no,$str,$file,$line) {
    throw new ErrorException($str,$no,0,$file,$line);
}

$socket = stream_socket_server("tcp://0.0.0.0:8000", $errno, $errstr);
if (!$socket) {
  echo "$errstr ($errno)\n";
} else {
  while ($conn = stream_socket_accept($socket)) {
    foreach (str_split('The local time is ' . date('n/j/Y g:i a') . "\n") as $char) {
      echo $char;
      try {
            fwrite($conn,$char);
      } catch (ErrorException $e) {
            if (preg_match("/^fwrite\(\): send of 1 bytes failed with errno=([0-9]+) ([A-Za-z \/]+)$/",$e->getMessage(), $matches)) {
                    list($errno,$errstr) = array((int) $matches[1], $matches[2]);
                    if ($errno === 32) {
                            echo "\n[ERROR] $errstr"; // Broken pipe
                    }
            }
            echo "\n[ERROR] Couldn't write more on $conn";
            break;
      }
      fflush($conn);
    }
    fclose($conn);
  }
  fclose($socket);
}
echo "\n";
?>

Запуск: php ./server.php

Подключение: nc localhost 8000 | head -c1

Вывод на сервер:

The loca
[ERROR] Broken pipe
[ERROR] Couldn't write more on Resource id #6
...