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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9841635/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 07:45:37  来源:igfitidea点击:

How can I ping a server port with PHP?

phpping

提问by user1288533

I want a PHP script which allows you to ping an IP address and a port number (ip:port). I found a similar script but it works only for websites, not ip:port.

我想要一个 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);

?>

I want this for a game server.

我想要这个用于游戏服务器。

The idea is that I can type in the IP address and port number, and I get the ping response.

这个想法是我可以输入 IP 地址和端口号,然后我得到 ping 响应。

回答by ShadowScripter

I think the answer to this questionpretty much sums up the problem with your question.

我认为这个问题的答案几乎总结了你的问题。

If what you want to do is find out whether a given host will accept TCP connections on port 80, you can do this:

$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);

For anything other than TCP it will be more difficult (although since you specify 80, I guess you are looking for an active HTTP server, so TCP is what you want). TCP is sequenced and acknowledged, so you will implicitly receive a returned packet when a connection is successfully made. Most other transport protocols (commonly UDP, but others as well) do not behave in this manner, and datagrams will not be acknowledged unless the overlayed Application Layer protocol implements it.

The fact that you are asking this question in this manner tells me you have a fundamental gap in your knowledge on Transport Layerprotocols. You should read up on ICMPand TCP, as well as the OSI Model.

如果您想要做的是找出给定主机是否会接受端口 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 模型

Also, here's a slightly cleanerversion to ping to hosts.

此外,这里有一个稍微干净的版本来 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;
}

回答by user1931751

In case the OP really wanted an ICMP-Ping, there are some proposals within the User Contributed Notes to socket_create()[link], which use raw sockets. Be aware that on UNIX like systems root access is required.

如果 OP 真的想要 ICMP-Ping,那么socket_create()[link]的用户贡献注释中有一些建议,它们使用原始套接字。请注意,在类 UNIX 系统上需要 root 访问权限。

Update: note that the usecargument has no function on windows. Minimum timeout is 1 second.

更新:请注意,该usec参数在 Windows 上没有任何功能。最小超时为 1 秒。

In any case, this is the code of the top voted ping function:

无论如何,这是投票最高的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;
}

回答by David Bélanger

Try this :

尝试这个 :

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

回答by T30

function ping($ip){
    $output = shell_exec("ping $ip");
    var_dump($output);
}
ping('127.0.0.1');

UPDATE: If you pass an hardcoded IP (like in this example and most of the real-case scenarios), this function can be enough.

更新:如果你传递一个硬编码的 IP(就像在这个例子和大多数真实案例中一样),这个函数就足够了。

But since some users seem to be very concerned about safety, please remind to neverpass user generated inputs to the shell_execfunction: If the IP comes from an untrusted source, at least check it with a filterbefore using it.

但是由于一些用户似乎非常关心安全,请提醒永远不要将用户生成的输入传递给shell_exec函数:如果 IP 来自不受信任的来源,至少在使用前使用过滤器检查它。

回答by Geo

Test different ports:

测试不同的端口:

$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

回答by Hymanie

You can use execfunction

您可以使用exec函数

 exec("ping ".$ip);

herean example

这里有一个例子

回答by markus

You don't need any exec or shell_exec hacks to do that, it is possible to do it in PHP. The book 'You want to do WHAT with PHP?' by Kevin Schroeder, show's how.

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

It uses sockets and the pack()function which lets you read and write binary protocols. What you need to do is to create an ICMP packet, which you can do by using the 'CCnnnA*' format to create your packet.

它使用套接字和pack()允许您读写二进制协议的功能。您需要做的是创建一个 ICMP 数据包,您可以使用“CCnnnA*”格式来创建您的数据包。

回答by PodTech.io

socket_create needs to be run as root on a UNIX system with;

socket_create 需要在 UNIX 系统上以 root 身份运行;

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

回答by jcubic

If you want to send ICMP packets in php you can take a look at this Native-PHP ICMP ping implementation, but I didn't test it.

如果你想在 php 中发送 ICMP 数据包,你可以看看这个Native-PHP ICMP ping implementation,但我没有测试它。

EDIT:

编辑:

Maybe the site was hacked because it seems that the files got deleted, there is copy in archive.orgbut you can't download the tar ball file, there are no contact email only contact form, but this will not work at archive.org, we can only wait until the owner will notice that sit is down.

也许该网站被黑了,因为文件似乎被删除了,archive.org 中副本,但您无法下载 tar ball 文件,没有联系电子邮件,只有联系表格,但这在 archive.org 上不起作用,我们只能等到主人注意到坐下。