web-dev-qa-db-ja.com

PHPでサーバーポートにpingを実行するにはどうすればよいですか?

IPアドレスとポート番号(ip:port)をpingできるPHPスクリプトが必要です。同様のスクリプトを見つけましたが、ip:portではなく、Webサイトでのみ機能します。

<?php

function ping($Host, $port, $timeout) 
{ 
  $tB = microtime(true); 
  $fP = fSockOpen($Host, $port, $errno, $errstr, $timeout); 
  if (!$fP) { return "down"; } 
  $tA = microtime(true); 
  return round((($tA - $tB) * 1000), 0)." ms"; 
}

//Echoing it will display the ping if the Host is up, if not it'll say "down".
echo ping("www.google.com", 80, 10);

?>

これはゲームサーバーに必要です。

IPアドレスとポート番号を入力すると、ping応答が返されます。

40
user1288533

この質問 への答えは、あなたの質問の問題をかなり要約していると思います。

特定のホストがポート80でTCP接続を受け入れるかどうかを確認する場合は、次の操作を実行できます。

$Host = '193.33.186.70'; 
$port = 80; 
$waitTimeoutInSeconds = 1; 
if($fp = fsockopen($Host,$port,$errCode,$errStr,$waitTimeoutInSeconds)){   
   // It worked 
} else {
   // It didn't work 
} 
fclose($fp);

TCP以外の場合はより困難になります(80を指定しているため、アクティブなHTTPサーバーを探していると思われるため、TCPが必要です)。 TCPはシーケンス化されて確認されるため、接続が正常に確立されると、返されたパケットを暗黙的に受信します。他のほとんどのトランスポートプロトコル(通常はUDPですが、他のトランスポートプロトコルも同様)はこの方法で動作せず、オーバーレイされたアプリケーション層プロトコルで実装されない限り、データグラムは確認されません。

この方法でこの質問をしているという事実は、 トランスポート層 プロトコルに関する知識に根本的なギャップがあることを示しています。 ICMP および TCP 、および OSI Model をお読みください。

また、ホストにpingするための わずかにクリーナー バージョンもあります。

// Function to check response time
function pingDomain($domain){
    $starttime = microtime(true);
    $file      = fsockopen ($domain, 80, $errno, $errstr, 10);
    $stoptime  = microtime(true);
    $status    = 0;

    if (!$file) $status = -1;  // Site is down
    else {
        fclose($file);
        $status = ($stoptime - $starttime) * 1000;
        $status = floor($status);
    }
    return $status;
}
68
ShadowScripter

OPがICMP-Pingを本当に必要としていた場合、User Contributed Notesにはsocket_create()[link] への提案があり、生のソケットを使用します。 UNIXのようなシステムではルートアクセスが必要であることに注意してください。

更新:usec引数にはWindowsの機能がないことに注意してください。最小タイムアウトは1秒です。

いずれにせよ、これはトップ投票されたping関数のコードです:

function ping($Host, $timeout = 1) {
    /* ICMP ping packet with a pre-calculated checksum */
    $package = "\x08\x00\x7d\x4b\x00\x00\x00\x00PingHost";
    $socket  = socket_create(AF_INET, SOCK_RAW, 1);
    socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => $timeout, 'usec' => 0));
    socket_connect($socket, $Host, null);
    $ts = microtime(true);
    socket_send($socket, $package, strLen($package), 0);
    if (socket_read($socket, 255)) {
        $result = microtime(true) - $ts;
    } else {
        $result = false;
    }
    socket_close($socket);
    return $result;
}
18
user1931751

これを試して :

echo exec('ping -n 1 -w 1 72.10.169.28');
3
David Bélanger

さまざまなポートをテストします。

$wait = 1; // wait Timeout In Seconds
$Host = 'example.com';
$ports = [
    'http'  => 80,
    'https' => 443,
    'ftp'   => 21,
];

foreach ($ports as $key => $port) {
    $fp = @fsockopen($Host, $port, $errCode, $errStr, $wait);
    echo "Ping $Host:$port ($key) ==> ";
    if ($fp) {
        echo 'SUCCESS';
        fclose($fp);
    } else {
        echo "ERROR: $errCode - $errStr";
    }
    echo PHP_EOL;
}


// Ping example.com:80 (http) ==> SUCCESS
// Ping example.com:443 (https) ==> SUCCESS
// Ping example.com:21 (ftp) ==> ERROR: 110 - Connection timed out
2
Geo
function ping($ip){
    $output = Shell_exec("ping $ip");
    var_dump($output);
}
ping('127.0.0.1');

更新:ハードコードされたIPを渡す場合(この例やほとんどの実際のシナリオのように)、この機能で十分です。

ただし、一部のユーザーは安全性を非常に懸念しているように見えるため、neverがユーザー生成入力をShell_exec関数に渡すことを思い出してください。信頼できないソースから提供されます。少なくとも、それを使用する前にチェックしてください フィルター付き

2
T30

これを行うためにexecやShell_execのハックは必要ありません。PHPで行うことができます。 「PHPで何をしたいですか?」という本ケビン・シュローダー、ショーの方法。

ソケットと、バイナリプロトコルを読み書きできるpack()関数を使用します。必要なのはICMPパケットを作成することです。これは、「CCnnnA *」形式を使用してパケットを作成することで実行できます。

1
markus

exec 関数を使用できます

 exec("ping ".$ip);

ここ

0
Jackie

ICMPパケットをphpで送信したい場合は、この ネイティブPHP ICMP ping実装 を見ることができますが、テストしませんでした。

0
jcubic

socket_createは、UNIXシステムでrootとして実行する必要があります。

$socket = socket_create(AF_UNIX, SOCK_STREAM, 0);
0
PodTech.io