8

我最近一直在使用 PHP 构建 TCP 服务器(我知道一开始的选择是错误的,但这是工作标准),所以我已经到了有一个可靠的原型可以对其进行测试并显示出良好结果的地步. 一开始我使用套接字函数来处理服务器的连接,它工作得很好,但是项目的主要内容之一是确保通道安全,所以我切换到了stream_socket。

我想要的是 stream_socket 组中的 socket_last_error 等效项,因此我可以知道与客户端的连接何时关闭。当前情况下,即使客户端已经关闭,所有进程都将等待超时计时器释放。

我在网上搜索过,我发现没有办法通过 PHP 来解决它,我发现有些人打开了关于它的问题票,要求 socket_last_error 等效于流。 https://bugs.php.net/bug.php?id=34380

那么无论何时引发 FIN_WAIT 信号,是否都知道?

谢谢,

4

1 回答 1

1

我觉得这不可能是stream_socket家庭,看起来它的级别太高了。

我尝试制作一个非常hackish的解决方案,我不知道它是否适合你,它不是很可靠:

<?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
于 2012-03-31T13:02:28.127 回答