我想要一个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);
?>
Run Code Online (Sandbox Code Playgroud)
我希望这个用于游戏服务器.
我的想法是我可以输入IP地址和端口号,然后我得到ping响应.
Sha*_*ter 70
我认为这个问题的答案几乎总结了你的问题.
如果您要做的是确定给定主机是否将接受端口80上的TCP连接,您可以这样做:
Run Code Online (Sandbox Code Playgroud)$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,但也包括其他传输协议)不会以这种方式运行,并且除非覆盖的应用层协议实现数据报,否则将无法确认数据报.
此外,这是一个稍微更清洁的版本,以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;
}
Run Code Online (Sandbox Code Playgroud)
use*_*751 18
如果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;
}
Run Code Online (Sandbox Code Playgroud)
测试不同端口:
$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
Run Code Online (Sandbox Code Playgroud)
尝试这个 :
echo exec('ping -n 1 -w 1 72.10.169.28');
Run Code Online (Sandbox Code Playgroud)
function ping($ip){
$output = shell_exec("ping $ip");
var_dump($output);
}
ping('127.0.0.1');
Run Code Online (Sandbox Code Playgroud)
更新:如果您传递硬编码的 IP(如本例和大多数实际情况),此功能就足够了。
但由于有些用户似乎非常关心安全,请提醒不要将用户生成的输入传递给该shell_exec
函数:如果 IP 来自不受信任的来源,至少在使用之前使用过滤器对其进行检查。