插座耗时太久无法关闭

时间:2012-09-07 21:46:13

标签: php sockets minecraft

我的套接字在我的应用程序的几个页面上查询游戏服务器。我有一个问题,当我在页面之间导航太快时,套接字没有正确关闭,我得到的错误就是这个;

socket_recv() [function.socket-recv]: unable to read from socket [104]: Connection reset by peer

我必须在每个页面完全加载后等待大约4-5秒才能关闭。

这是套接字的代码;

function QueryMinecraft( $IP, $Port, $Timeout =1 )
{
    $Socket = Socket_Create( AF_INET, SOCK_STREAM, SOL_TCP );

    Socket_Set_Option( $Socket, SOL_SOCKET, SO_SNDTIMEO, array( 'sec' => (int)$Timeout, 'usec' => 0 ) );

    if( $Socket === FALSE || @Socket_Connect( $Socket, $IP, (int)$Port ) === FALSE )
    {
        Socket_Close( $Socket );
        return FALSE;
    } else {
        Socket_Close( $Socket );
        return TRUE;
    }      
    Socket_Close( $Socket );                  
}   

这是另一页上套接字的代码;

function QueryMinecraft( $IP, $Port, $Timeout = 3 )
{
    $Socket = Socket_Create( AF_INET, SOCK_STREAM, SOL_TCP );

    Socket_Set_Option( $Socket, SOL_SOCKET, SO_SNDTIMEO, array( 'sec' => (int)$Timeout, 'usec' => 0 ) );

    if( $Socket === FALSE || @Socket_Connect( $Socket, $IP, (int)$Port ) === FALSE )
    {
        return FALSE;
    }

    Socket_Send( $Socket, "\xFE", 1, 0 );
    $Len = Socket_Recv( $Socket, $Data,256, 0 );


    if( $Len < 4 || $Data[ 0 ] != "\xFF" )
    {
        return FALSE;
    }

    $Data = SubStr( $Data, 3 );
    $Data = iconv( 'UTF-16BE', 'UTF-8', $Data );
    $Data = Explode( "\xA7", $Data );

    return Array(
        'HostName'   => SubStr( $Data[ 0 ], 0, -1 ),
        'Players'    => isset( $Data[ 1 ] ) ? IntVal( $Data[ 1 ] ) : 0,
        'MaxPlayers' => isset( $Data[ 2 ] ) ? IntVal( $Data[ 2 ] ) : 0
    );
}

谢谢!

1 个答案:

答案 0 :(得分:3)

哇哇,我知道的具体知识很多!应该有一个Minecraft标签。

我认为这实际上是一个Minecraft服务器限制,而不是你的php代码的问题。您可能会注意到,如果您正在使用Minecraft客户端并且您多次快速访问多人游戏页面,您将遇到相同的问题(与服务器的连接以查询玩家数量并且MOTD将被拒绝)。如果你在两次访问之间等待5或6秒,它就会自行解决。

因此,您的解决方案可能是将服务器的响应缓存10秒或30秒左右,以便服务器不会拒绝它们。

我不知道你是否有一个可以使用的本地SQL数据库,但是你应该可以设置一个包含服务器ip的表(不是主机名,不保证是唯一的.IP isn不是,但它是一个更好的赌注),MOTD,当前和最大玩家,以及最后检查的时间戳。您可以简单地进行数据库查询,检查时间戳以确保缓存的值没有过期,如果有,则直接查询服务器并将结果存储在数据库中。