8

私は最近、PHP を使用して TCP サーバーを構築する作業を行っています (最初は間違った選択をしていることはわかっていますが、これが作業の標準です)。そのため、テストを実行するための信頼できるプロトタイプがあり、良い結果が得られるようになりました。 . 最初はソケット関数を使用してサーバーへの接続を処理しましたが、うまく機能していましたが、プロジェクトの主な目的の 1 つはチャネルを保護することなので、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、レベルが高すぎるようだ。

私は非常にハックなソリューションを作成しようとしましたが、それがうまくいくかどうかはわかりません.あまり信頼できません:

<?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 に答える