実際の時間を提供し、すぐに接続を閉じる簡単な PHP サーバー (TCP ベース) を作成したいと考えています。私はすでにそれをしました。crtl-C 処理を追加したかったので、ブロッキング socket_accept を非ブロッキングに置き換える必要がありました (これは、ブロッキング socket_accept 命令に到達し、SIGINT /ctrl-C/ を送信すると、最初のクライアントまでサーバーがまだ生きているためです)。サーバーであり、それ自体を閉じます-そして、私はこの動作を望んでいませんでした)。
私の現在のコードは次のようになります。
<?php
error_reporting(E_ALL);
ob_implicit_flush();
if ($argc != 2)
die("Wrong params");
$address = 'localhost';
$port = $argv[1];
if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false)
die(socket_strerror(socket_last_error()) . "\n");
if (socket_bind($sock, $address, $port) === false)
die(socket_strerror(socket_last_error($sock)) . "\n");
if (socket_listen($sock, 5) === false)
die(socket_strerror(socket_last_error($sock)) . "\n");
socket_set_nonblock($sock);
$remote_host = $remote_port = $msgsock = null;
declare(ticks = 1);
function sig_handler($signo)
{
switch ($signo) {
case SIGTERM:
case SIGINT:
global $sock;
socket_shutdown($sock);
socket_close($sock);
echo "Terminating...\n";
exit;
}
}
pcntl_signal(SIGTERM, "sig_handler");
pcntl_signal(SIGINT, "sig_handler");
echo "Starting server\n";
while (1) {
do {
$msgsock = socket_accept($sock);
usleep(100000);
} while ($msgsock === false);
socket_getpeername($msgsock, $remote_host, $remote_port);
echo "Connection made from {$remote_host}:{$remote_port}\n";
$msg = date('r', time()) . "\n";
socket_write($msgsock, $msg, strlen($msg));
socket_close($msgsock);
};
socket_close($sock);
1 つの詳細を除いてすべて正常に動作しています... 0.1 秒 (= 100000 マイクロ秒) ごとに次の PHP 警告が表示されます。
PHP Warning: socket_accept(): unable to accept incoming connection [11]: Resource temporarily unavailable in /home/tomasz/Development/Python/twisted/time-server.php on line 55
PHP Stack trace:
PHP 1. {main}() /home/tomasz/Development/Python/twisted/time-server.php:0
PHP 2. socket_accept() /home/tomasz/Development/Python/twisted/time-server.php:55
私が達成しようとしたのは、ノンブロッキングの受け入れです。PHP はサーバー ソケットを使用し、提供されるのを待っている接続があるかどうかを確認します。いいえ - 0.1 秒待ちます。保留中の接続がある場合は、それを提供します。この警告がスローされる理由がわからないことを除いて、すべての機能は問題ありません。提供される接続があるかどうかを確認したいだけです。に変更error_reporting
するE_ERROR
と警告が静かになりますが、それを解決するためのより良い方法があることを願っています...
編集:
に変更socket_accept($sock)
する@socket_accept($sock)
と、警告がスローされるのが抑制されますが、それでもスローされる理由は述べられていません...