Как сделать ограничение по времени для сокетов? - PullRequest
0 голосов
/ 09 января 2012

Как сделать ограничение времени сокета? http://pastebin.com/0q3NeLAX

Я пробовал socket_time_limit и другие, но это не помогло.

Я хочу, чтобы, если сокет не получил никакой информации, он был закрыт через X секунд.

function QueryMinecraft( $IP, $Port = 25565 )
{
    $Socket = Socket_Create( AF_INET, SOCK_STREAM, SOL_TCP );
    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 );
    Socket_Close( $Socket );

    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 голосов
/ 19 января 2012

Я бы не использовал для этого расширение сокетов, я использую его только для расширенных операций с сокетами, которые нельзя выполнить с помощью fsockopen().Причина этого в том, что расширение сокетов не всегда доступно, тогда как fsockopen() обычно есть.

Вот как я бы написал ваш код с таймаутом получения данных:

function QueryMinecraft( $IP, $Port = 25565 )
{

    // Seconds to wait for a successful connection
    $connectTimeout = 5;
    // Seconds to wait for data
    $receiveTimeout = 5;

    $Socket = fsockopen($IP, $port, $errNo, $errStr, $connectTimeout);

    if( !$Socket || !stream_set_timeout( $Socket, $receiveTimeout ) )
    {
        return FALSE;
    }

    fwrite( $Socket, "\xFE" );
    $Data = fread( $Socket, 256 );
    fclose( $Socket );

    if( strlen( $Data ) < 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
    );

}
...