2012-03-31 3 views
8

최근에 PHP를 사용하여 TCP 서버를 작성하는 작업을 시작했습니다. (시작하는 것은 잘못된 선택입니다.하지만 이것이 작업 표준입니다.) 그래서 테스트를 수행 할 신뢰할 수있는 프로토 타입이있는 지점에 도달했습니다. 좋은 결과. 시작시 소켓 함수를 사용하여 서버 연결을 처리했으며 잘 작동했지만 프로젝트의 주요 기능 중 하나는 채널 보안을 설정하여 stream_socket으로 전환하는 것입니다.PHP에서 피어에 의해 연결이 재설정 될 때마다 어떻게 알 수 있습니까?

내가 원하는 것은 stream_socket 그룹에 해당하는 socket_last_error이므로 클라이언트와의 연결이 닫힐 때마다 알 수 있습니다. 현재 상황은 모든 프로세스가 클라이언트가 이미 닫혀 있어도 타임 아웃 타이머가 해제 될 때까지 대기합니다.

그물을 검색 한 결과 PHP를 통해 알아낼 방법이 없다는 것을 알았습니다. 일부 사람들이 스트림에 대해 socket_last_error를 요구하는 티켓을 발급 한 것으로 나타났습니다. https://bugs.php.net/bug.php?id=34380

FIN_WAIT 신호가 발생할 때마다 알 수 있습니까?

답변

1

나는 그것이 너무 높은 수준의 같은 stream_socket 가족, 보이는 가능하다고 생각하지 않습니다, 감사합니다.

, 그것은 매우 신뢰할 수있는 내가 당신을 위해 작동하는지 매우 hackish 솔루션, 나도 몰라 만드는 시도

을 아니다 :

<?php 
set_error_handler('my_error_handler'); 

function my_error_handler($no,$str,$file,$line) { 
    throw new ErrorException($str,$no,0,$file,$line); 
} 

$socket = stream_socket_server("tcp://0.0.0.0:8000", $errno, $errstr); 
if (!$socket) { 
    echo "$errstr ($errno)\n"; 
} else { 
    while ($conn = stream_socket_accept($socket)) { 
    foreach (str_split('The local time is ' . date('n/j/Y g:i a') . "\n") as $char) { 
     echo $char; 
     try { 
      fwrite($conn,$char); 
     } catch (ErrorException $e) { 
      if (preg_match("/^fwrite\(\): send of 1 bytes failed with errno=([0-9]+) ([A-Za-z \/]+)$/",$e->getMessage(), $matches)) { 
        list($errno,$errstr) = array((int) $matches[1], $matches[2]); 
        if ($errno === 32) { 
          echo "\n[ERROR] $errstr"; // Broken pipe 
        } 
      } 
      echo "\n[ERROR] Couldn't write more on $conn"; 
      break; 
     } 
     fflush($conn); 
    } 
    fclose($conn); 
    } 
    fclose($socket); 
} 
echo "\n"; 
?> 

시작 : php ./server.php

연결 : nc localhost 8000 | head -c1

서버 출력 :

The loca 
[ERROR] Broken pipe 
[ERROR] Couldn't write more on Resource id #6 
+0

감사합니다. 아시다시피 스트림이 손상 될 때마다 데이터를 보내서 스트림을 소음으로 처리하는 것이 가능하지 않다는 것을 알고 있으므로 서버가 클라이언트 작업을 기다리는 것이므로 현재 상황은 가능하다고 생각하지 않습니다. – user1304594