簡體   English   中英

如何使用 PHP ping 服務器端口?

[英]How can I ping a server port with PHP?

我想要一個 PHP 腳本,它允許您 ping 一個 IP 地址和一個端口號( ip:port )。 我找到了一個類似的腳本,但它僅適用於網站,不適用於ip:port

<?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 響應。

我認為這個問題的答案幾乎總結了你的問題。

如果您想要做的是找出給定主機是否會接受端口 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,但也有其他協議)不會以這種方式運行,除非覆蓋的應用層協議實現它,否則不會確認數據報。

你要求以這種方式這個問題的事實告訴我,你有你的知識的根本差距傳輸層協議。 您應該閱讀ICMPTCP以及OSI 模型

此外,這里有一個稍微干凈的版本來 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;
}

如果 OP 真的想要 ICMP-Ping,那么在socket_create() [link]的用戶貢獻注釋中有一些建議,它們使用原始套接字。 請注意,在類 UNIX 系統上需要 root 訪問權限。

更新:請注意, 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;
}

嘗試這個 :

echo exec('ping -n 1 -w 1 72.10.169.28');

測試不同的端口:

$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
function ping($ip){
    $output = shell_exec("ping $ip");
    var_dump($output);
}
ping('127.0.0.1');

更新:如果你傳遞一個硬編碼的 IP(就像在這個例子和大多數真實案例中一樣),這個函數就足夠了。

但是由於一些用戶似乎很關心安全,請提醒永遠不要將用戶生成的輸入傳遞給shell_exec函數:如果 IP 來自不受信任的來源,至少在使用之前用過濾器檢查它。

您可以使用exec函數

 exec("ping ".$ip);

這里有一個例子

socket_create 需要在 UNIX 系統上以 root 身份運行;

$socket = socket_create(AF_UNIX, SOCK_STREAM, 0);

你不需要任何 exec 或 shell_exec hacks 來做到這一點,可以在 PHP 中做到這一點。 “你想用 PHP 做什么?”這本書作者:Kevin Schroeder,展示如何。

它使用套接字和pack()函數,讓您可以讀寫二進制協議。 您需要做的是創建一個 ICMP 數據包,您可以使用“CCnnnA*”格式來創建您的數據包。

如果你想在 php 中發送 ICMP 數據包,你可以看看這個Native-PHP ICMP ping implementation ,但我沒有測試它。

編輯:

也許該網站被黑了,因為文件似乎被刪除了, archive.org 中副本,但您無法下載 tar ball 文件,沒有聯系電子郵件,只有聯系表格,但這在 archive.org 上不起作用,我們只能等到主人注意到坐下。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM