2012-09-07 5 views
3

응용 프로그램의 몇 페이지에서 게임 서버에 소켓을 쿼리합니다. 페이지 사이를 너무 빠르게 탐색 할 때 소켓이 제대로 닫히지 않았고 오류가 발생하는 문제가 있습니다.소켓을 닫는 데 너무 오래 걸림

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 
    ); 
} 

고마워요!

답변

3

우후, 특정 지식 나는 많은 것을 알고 있습니다! minecraft 태그가 있어야합니다.

이것은 PHP 코드의 문제와는 반대로 실제로 이것은 미니 크래프트 서버 제한이라고 생각합니다. 멀티 플레이어 클라이언트를 사용 중이고 멀티 플레이 페이지를 빠르게 여러 번 방문하면 같은 문제가 발생할 수 있습니다 (플레이어 수를 쿼리하고 MOTD에 대한 서버 연결이 거부 됨). 그것은 방문 사이에 5 ~ 6 초를 기다리면 스스로 해결됩니다.

따라서 솔루션은 서버의 응답을 10 초 또는 30 초 정도 캐시하여 서버가 거부하지 않도록 할 수 있습니다.

사용할 수있는 로컬 SQL 데이터베이스가 있는지 모르겠지만 서버 IP가 포함 된 테이블을 설정할 수 있어야합니다 (고유 한 호스트 이름이 아닌) .IP 더 좋은 내기는 아니지만), MOTD, 현재 및 최대 선수, 마지막으로 확인 된 시간 기록. 데이터베이스 쿼리를 수행하고 타임 스탬프를 확인하여 캐시 된 값이 만료되지 않았는지 확인한 다음 서버에 직접 쿼리하고 결과를 데이터베이스에 저장할 수 있습니다.

+0

서버 코드를 샅샅이 뒤졌지만,이 동작의 보편성으로 판단 할 때, 서버의 동작은 매우 오랜 시간이었습니다. – Wug

+0

좋아, 그게 정말 짜증나, 페이지로드 느린 롤을 만들 수 있습니다 : L –

+0

답장을 보내 주셔서 감사합니다, 내가 뭔가를 3 초 페이지로드를 일시 중지 수 있습니다. –

관련 문제