PHP游戏服务器查询

PHP游戏服务器查询,php,Php,我有一个脚本,我发现它可以查询SRCDS游戏服务器并输出诸如主机名、IP、连接的玩家等信息(注意,我对它进行了编辑,所以它只显示当前连接的玩家和地图)。我希望该脚本首先ping服务器以检查它是否在线,然后继续查询 PHP脚本 function source_query($ip){ $cut = explode(":", $ip); $HL2_address = $cut[0]; $HL2_port = $cut[1]; $HL2_command = "\377\377\377\377TSour

我有一个脚本,我发现它可以查询SRCDS游戏服务器并输出诸如主机名、IP、连接的玩家等信息(注意,我对它进行了编辑,所以它只显示当前连接的玩家和地图)。我希望该脚本首先ping服务器以检查它是否在线,然后继续查询

PHP脚本

function source_query($ip){
$cut = explode(":", $ip);
$HL2_address = $cut[0];
$HL2_port = $cut[1];

$HL2_command = "\377\377\377\377TSource Engine Query\0";

$HL2_socket = fsockopen("udp://".$HL2_address, $HL2_port, $errno, $errstr,3);
fwrite($HL2_socket, $HL2_command); 
$JunkHead = fread($HL2_socket,4);
$CheckStatus = socket_get_status($HL2_socket);

if($CheckStatus["unread_bytes"] == 0)return 0;

$do = 1;
while($do){
    $str = fread($HL2_socket,1);
    $HL2_stats.= $str;
    $status = socket_get_status($HL2_socket);
    if($status["unread_bytes"] == 0){
           $do = 0;
    }
}
fclose($HL2_socket);

$x = 0;
while ($x <= strlen($HL2_stats)){
    $x++;
    $result.= substr($HL2_stats, $x, 1);    
}

// ord ( string $string );
$result = str_split($result);
$info['network'] = ord($result[0]);$char = 1;
while(ord($result[$char]) != "%00"){$info['name'] .= $result[$char];$char++;}$char++;
while(ord($result[$char]) != "%00"){$info['map'] .= $result[$char];$char++;}$char++;
while(ord($result[$char]) != "%00"){$info['dir'] .= $result[$char];$char++;}$char++;
while(ord($result[$char]) != "%00"){$info['description'] .= $result[$char];$char++;}$char++;
$info['appid'] = ord($result[$char].$result[($char+1)]);$char += 2;        
$info['players'] = ord($result[$char]);$char++;    
$info['max'] = ord($result[$char]);$char++;    
$info['bots'] = ord($result[$char]);$char++;    
$info['dedicated'] = ord($result[$char]);$char++;    
$info['os'] = chr(ord($result[$char]));$char++;    
$info['password'] = ord($result[$char]);$char++;    
$info['secure'] = ord($result[$char]);$char++;    
while(ord($result[$char]) != "%00"){$info['version'] .= $result[$char];$char++;}

return $info;
}
我希望服务器事先被ping。如果它是在线的,它会像上面那样做,但如果它是离线的,我希望它回显“离线”,删除

Players: /
Map: 
并且不要继续查询,以最小化加载页面所需的时间。

根据 fSOCKOPEN/<代码>,特别是对于UDP连接,您应该考虑做更多的错误处理:

警告

UDP套接字有时看起来打开时没有错误, 即使无法访问远程主机。错误只会变得更严重 当您在套接字中读取或写入数据时,这一点很明显。原因 因为UDP是一种“无连接”协议,这意味着 操作系统不会尝试为 套接字,直到它实际需要发送或接收数据


这很可能不会大大加快速度,但至少可能比你现在拥有的要好。但是,我要注意的是,PHP手册中提到了
未读字节
用法:
注意:您不应该在脚本中使用此值。
您还可以减少调用
fsockopen
的超时时间(最后一个参数)

function ping($host)
{
    exec(sprintf('ping -c 1 -W 5 %s', escapeshellarg($host)), $res, $rval);
    return $rval === 0;
}

$HL2_command = "\377\377\377\377TSource Engine Query\0";

if(!ping($HL2_address))
{
    return 0;
}

$HL2_socket = fsockopen("udp://".$HL2_address, $HL2_port, $errno, $errstr,3);
显示代码

include 'status.php'; // name of file including above script
$q = source_query('ip:port'); // replaced with real IP address and port
echo "Players: " .$q['players'];
echo "/" .$q['max'];
echo "<br>";
echo "Map: ".$q['map'];
include 'status.php'; // name of file including above script
$q = source_query('ip:port'); // replaced with real IP address and port

if($q === 0)
{
    echo "Offline";
}
else
{
    echo "Players: " .$q['players'];
    echo "/" .$q['max'];
    echo "<br>";
    echo "Map: ".$q['map'];
}
包括“status.php”;//包含上述脚本的文件名
$q=source_查询('ip:port');//替换为实际IP地址和端口
如果($q==0)
{
回应“离线”;
}
其他的
{
回声“玩家:”.$q[“玩家];
echo“/”$q['max'];
回声“
”; 回声“地图:”.$q[“地图]; }
如果服务器在线或存在,则此操作有效。然而,它并不像上面提到的那样。如果服务器脱机,它会尝试查询它,这需要很长时间。这就是为什么我想包括ping功能来检查它是否在线,然后再进行任何查询@你对“离线”的定义是什么?整个服务器都停机了?无法访问特定端口?你得到一个空的答复?确定服务器是否“脱机”可能需要一点时间。这就是我建议降低超时的原因。所谓“脱机”,我指的是上述所有内容。例如,如果我选择192.168.1.1:80,而端口80上没有运行任何内容,则页面需要很长时间才能“脱机”加载。在查询地址之前,预先ping地址以检查是否确实存在某些内容并作出响应,这不是更可行吗?我真的不知道这是否有意义。此外,超时设置为4秒,但如果页面查询的内容不存在/脱机,则加载页面所需的时间要长得多。请看一看-注意加载要花很长时间。@JakeGriffin检查我的更新。它使用来自的功能。您还可以查看,因为可能是
fwrite
fread
调用花费了很长时间。感谢迄今为止的帮助,但是您的更新现在会使它无论发生什么都显示为“脱机”!当然,现在速度要快得多:P
include 'status.php'; // name of file including above script
$q = source_query('ip:port'); // replaced with real IP address and port

if($q === 0)
{
    echo "Offline";
}
else
{
    echo "Players: " .$q['players'];
    echo "/" .$q['max'];
    echo "<br>";
    echo "Map: ".$q['map'];
}