БлогNot. Проверка доступности сервера на PHP

Проверка доступности сервера на PHP

Проверить доступность одного Web-сервера легко с помощью стандартной функции fsockopen:

<?php
 $server = 'www.yandex.ru';
 $port = 80;
 $status = 'unavailable';
 $timeout = 10;
 $fp = @fsockopen ($server, $port, $errno, $errstr, $timeout);
 if ($fp) {
  $status = 'alive, not responding';
  @fwrite ($fp, "HEAD / HTTP/1.0\r\nHost: $server:$port\r\n\r\n");
  if (strlen(@fread($fp,1024))>0) $status = 'alive, responding';
  fclose ($fp);
 }
 echo "$server status is $status"; 
?>

Однако для проверки состояния нескольких серверов такой подход едва ли годится - вызов функции fsockopen может длиться столько секунд, сколько указано в её последнем параметре, и только затем будет выполнена следующая команда сценария. Используя PHP 5 и потоковые сокеты задачу можно выполнить и асинхронно, правда, код станет сложнее:

<?php
$hosts = array("www.yandex.ru", "www.google.ru", "www.mail.ru");
$timeout = 10; //Время ожидания, сек.
$status = array(); //Статусы хостов
$sockets = array(); //Сокеты

// Законнектиться ко всем хостам
foreach ($hosts as $id => $host) {
 $s = @stream_socket_client ("$host:80", $errno, $errstr, $timeout, 
  STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT);
 if ($s) {
  $sockets[$id] = $s;
  $status[$id] = "in progress";
 } else {
  $status[$id] = "failed, $errno $errstr";
 }
}

//Ждём ответов
while (count($sockets)) {
 $read = $write = $sockets;
 $n = stream_select ($read, $write, $e = null, $timeout);
 if ($n > 0) {
  foreach ($read as $r) {
   $id = array_search($r, $sockets);
   $data = fread($r, 8192);
   if (strlen($data) == 0) {
    if ($status[$id] == "in progress") {
     $status[$id] = "failed to connect";
    }
    fclose($r);
    unset ($sockets[$id]);
   } 
   else {
    $status[$id] .= $data;
   }
  }
  foreach ($write as $w) {
   $id = array_search($w, $sockets);
   @fwrite ($w, "HEAD / HTTP/1.0\r\nHost: " . $hosts[$id] . "\r\n\r\n");
   $status[$id] = "waiting for response";
  }
 } 
 else {
  foreach ($sockets as $id => $s) {
   $status[$id] = "timed out " . $status[$id];
  }
  break;
 }
}

//Вывод результатов
foreach ($hosts as $id => $host) {
 echo "Host: $host Status: " . $status[$id] . "<br>\n";
}
?>

На локалхосте Windows, несмотря на подавление вывода сообщений об ошибках от функции stream_select, Вы рискуете получить лишь

Warning: Invalid CRT parameters detected in C:\Inetpub\wwwroot\socks.php on line 22

Причина думаю, в таком же баге, на *nix-сервере пример сработал.

11.05.2012, 16:55 [14290 просмотров]


теги: ошибка windows php сервер

К этой статье пока нет комментариев, Ваш будет первым