【问题标题】:PHP Gameserver QueryPHP 游戏服务器查询
【发布时间】:2014-02-20 20:13:27
【问题描述】:

我有一个脚本,我发现它可以查询 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;
}

显示代码

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'];

澄清一下:这个脚本可以很好地返回当前连接的玩家和服务器在线时正在播放的当前地图。当服务器离线时加载一段时间然后打印

Players: /
Map: 

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

Players: /
Map: 

不要继续查询,以尽量减少加载页面所需的时间。

【问题讨论】:

    标签: php


    【解决方案1】:

    这很可能不会大大加快速度,但至少可能比您现在拥有的要好。但是,我会注意到 PHP 手册中提到了 unread_bytes 用法:Note: You shouldn't use this value in a script. 您还可以减少对 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
    
    if($q === 0)
    {
        echo "Offline";
    }
    else
    {
        echo "Players: " .$q['players'];
        echo "/" .$q['max'];
        echo "<br>";
        echo "Map: ".$q['map'];
    }
    

    【讨论】:

    • 如果服务器在线或存在,此方法有效。但是,它并没有像上面提到的那样做。如果服务器离线,它会尝试查询它,这需要很长时间。这就是为什么我想包含 ping 功能以在进行任何查询之前检查它是否在线!
    • @JakeGriffin 您对“离线”的定义到底是什么?整个服务器都挂了?特定端口无法访问?你得到一个空洞的回应?确定服务器是否“离线”可能需要一点时间。这就是我建议降低超时的原因。
    • “离线”是指以上所有内容。例如,如果我选择了 192.168.1.1:80 并且端口 80 上没有运行任何东西,那么页面加载“离线”需要很长时间。事先 ping 地址以检查是否确实存在并在查询之前做出响应不是更可行吗?我真的不知道这是否有意义。此外,超时设置为 4 秒,但如果它正在查询不存在/离线的内容,则页面加载需要更长的时间。看看this - 请注意加载需要很长时间。
    • @JakeGriffin 检查我的更新。它使用来自this post 的功能。您还可以查看stream_set_timeout,因为它可能是需要很长时间的fwritefread 调用。
    • 感谢您迄今为止的帮助,但是您的更新现在无论如何都会显示“离线”!当然,现在速度快了很多:P
    【解决方案2】:

    根据fsockopenmanual,特别是对于UDP连接,应该考虑做更多的错误处理:

    警告

    UDP 套接字有时会看似已打开而没有错误, 即使远程主机无法访问。错误只会变成 当您从套接字读取或写入数据时很明显。原因 这是因为 UDP 是“无连接”协议,这意味着 操作系统不会尝试为 直到它真正需要发送或接收数据。

    【讨论】:

      猜你喜欢
      • 2016-10-05
      • 2012-06-16
      • 1970-01-01
      • 2011-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-14
      相关资源
      最近更新 更多