简体   繁体   English

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

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

I want a PHP script which allows you to ping an IP address and a port number ( ip:port ).我想要一个 PHP 脚本,它允许您 ping 一个 IP 地址和一个端口号( ip:port )。 I found a similar script but it works only for websites, not 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 响应。

I think the answer to this question pretty 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:如果您想要做的是找出给定主机是否会接受端口 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);

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 之外的任何其他内容,它将更加困难(尽管由于您指定了 80,我猜您正在寻找一个活动的 HTTP 服务器,因此 TCP 是您想要的)。 TCP is sequenced and acknowledged, so you will implicitly receive a returned packet when a connection is successfully made. TCP 被排序和确认,所以当连接成功时你会隐式地收到一个返回的数据包。 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.大多数其他传输协议(通常是 UDP,但也有其他协议)不会以这种方式运行,除非覆盖的应用层协议实现它,否则不会确认数据报。

The fact that you are asking this question in this manner tells me you have a fundamental gap in your knowledge on Transport Layer protocols.你要求以这种方式这个问题的事实告诉我,你有你的知识的根本差距传输层协议。 You should read up on ICMP and TCP , as well as the OSI Model .您应该阅读ICMPTCP以及OSI 模型

Also, here's a slightly cleaner version 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;
}

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.如果 OP 真的想要 ICMP-Ping,那么在socket_create() [link]的用户贡献注释中有一些建议,它们使用原始套接字。 Be aware that on UNIX like systems root access is required.请注意,在类 UNIX 系统上需要 root 访问权限。

Update: note that the usec argument has no function on windows.更新:请注意, usec参数在 Windows 上没有任何功能。 Minimum timeout is 1 second.最小超时为 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;
}

尝试这个 :

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

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
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 never pass user generated inputs to the shell_exec function: If the IP comes from an untrusted source, at least check it with a filter before using it.但是由于一些用户似乎很关心安全,请提醒永远不要将用户生成的输入传递给shell_exec函数:如果 IP 来自不受信任的来源,至少在使用之前用过滤器检查它。

You can use exec function您可以使用exec函数

 exec("ping ".$ip);

here an example这里有一个例子

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

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

You don't need any exec or shell_exec hacks to do that, it is possible to do it in PHP.你不需要任何 exec 或 shell_exec hacks 来做到这一点,可以在 PHP 中做到这一点。 The book 'You want to do WHAT with PHP?' “你想用 PHP 做什么?”这本书by Kevin Schroeder, show's how.作者:Kevin Schroeder,展示如何。

It uses sockets and the pack() function which lets you read and write binary protocols.它使用套接字和pack()函数,让您可以读写二进制协议。 What you need to do is to create an ICMP packet, which you can do by using the 'CCnnnA*' format to create your packet.您需要做的是创建一个 ICMP 数据包,您可以使用“CCnnnA*”格式来创建您的数据包。

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.org but 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 上不起作用,我们只能等到主人注意到坐下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM