2012-08-31 3 views
1

소켓에 다소 특이한 문제가 있습니다. 설정의 기초는 PHP로 작성된 포크 소켓 서버입니다. (나는 알고있다, PHP, 우우, 등, 등)이의fgets()는 socket_select 뒤에 빈 문자열을 반환합니다.

아주 기본적인 코드 샘플은

$controlSockets = stream_socket_pair(); 
$pid = pcntl_fork(); 
if($pid == -1) 
    throw new Exception("Fork error"); 
else if($pid) { 
    fclose($controlSockets[0]); 

    while(true) { 
      $read = array($controlSockets[1]); 
      $write = array(); 
      $except = array(); 

      // Sleep for half a second if there's nothing to read 
      while(stream_select($read, $write, $except, 0, 500000) > 0) { 
       $r = fgets($controlSockets[1]); 
       echo "'$r'\n read from socket."; // This outputs '' 
      } 

      // Re-set the read array as stream_select alters the array 
      $read = array($controlSockets[1]); 
    } 

} else { 
    fclose($controlSockets[1]); 
    // do some work ... 
    sleep(5); 
    // end of work ... 
    $result = 'blah'; 
    fputs($controlSockets[0], $result); 
    exit; 
} 

이제 문제는 ... 것이 그 소켓이 읽기에 포함 된 경우에도 컬렉션, 그러나 그것은 내 지식에 일어날 일은해서는 안된다, feof에 도달하지 않았거나 실제로 내용이있는 빈 문자열을 리턴한다. 처음 5 초 동안 실행되지 않습니다.

보내지는 실제 콘텐츠는 도착해도 괜찮습니다.

무슨 일인지에 대한 단서가 있습니까?

(위의 코드입니다 의사이며, 실제 샘플이 작동하지만, 무슨 일인지 일반적인 생각인지 전혀 생각) 점의

+0

내 좋은 방법은 문제가 실제 코드가 소켓에 예제 코드가하는 같은 방법을 쓰지 않는 것입니다. (PIPE_BUF 바이트 미만의 단일 쓰기.) 예제 코드에서 동일한 문제가 발생하는지 확인하십시오. 그렇지 않으면 실제 문제를 식별하는 데 도움이되지 않습니다. –

+0

사실 충분합니다. 일반적인 전송 크기는 13b 이상에서 (이론적으로) 무한대 사이입니다. –

답변

0

커플 :

  • 당신은 500 밀리의 제한 시간을 지정을, 5 초 동안 입력을 보내지 않으므로 select가 실제로 시간 초과되어 0을 반환해야합니다.
  • 당신은 (, 신호의 중단 등을)이 docs에 따라 울부 짖는 소리 같은 것을해야하는 `stream_select()에서 반환 된 오류를 확인하지 않습니다는 :

    if (false === ($num_changed_streams = stream_select(...

+0

알아. 이 코드는 코드의 실제 (아주!) 작은 하위 집합이며 모든 오류 검사가 제거됩니다. 5 초의 제한 시간은 일반적으로 분기 프로세스에 걸리는 시간입니다. 폴링 간격은 500ms입니다. 실제 상황에서는 1에서 8 개의 프로세스가 동시에 실행됩니다. 실제 상황에서는 모든 SIGCHLD (및 SIGTRM 등)를 포착하는 posix_signal 처리기가 있습니다. 이 질문의 핵심은 : 읽을 소켓 데이터가 없어도이 소켓이 stream_select에서 반환되는 이유는 무엇입니까? 처음에는 생각했습니다. –

+0

@ 마크, 실제 코드를 게시 한 다음 적어도 선택을 수행하는 부분. –

0

코드는 오류 조건을 불면 . fgets이 실패하면 여전히 출력됩니다. 아마도 소켓이 닫히면 stream_select이 실패 할 것으로 예상되지만 그렇지 않을 것입니다. 소켓을 확인해야 할 필요가 있음을 알려줍니다.

내가 얻을 :

'blah' 
read from socket.'' 
read from socket.'' 
[... repeats] 
관련 문제