2014-07-09
사용예
$errno = $errstr = NULL;
$this->socket = @fsockopen($this->server, $this->port, $errno, $errstr, 10);
if($this->socket == false)
{
 $this->log("Unable to connect to manager {$this->server}:{$this->port} ($errno): $errstr");
 return false;
} else
stream_set_timeout($this->socket, 2);


참조 : http://blueamor.tistory.com/318


삭제 대비용 원본글 복사

회사일중에 소켓을 이용해서 다른 웹서비스의 xml데이터를 받아서 처리하는 작업이 있었다.

별 문제 없이 처리했으나 서비스를 하던중 문제가 발생했다.

xml을 제공하는 웹서비스의 서버 상태가 불안해서 처리 작업이 진행이 안되고 멈춰있는 경우가 종종 발생한 것이다.

소켓 연결 실패 라던가 무한 루프 등의 예외 처리는 해 놓은 상태였지만

소켓 연결이 성공한 상황에서 데이터를 받지 못해서 처리작업이 신호대기 상태로 멈춰있는 경우였다.

방법이 없을까 고민하던중 php.net에서 다음과 같은 함수를 찾았다.

stream_set_timeout와 socket_set_timeout이다.

다른 함수처럼 보이지만 결과는 같다. 

stream_set_timeout은 데이터 스트림 수신 대기시간의 타임 아웃을 설정하는것이고
socket_set_timeout은 소켓 연결중 데이터 송수신 없이 대기하는 타임아웃을 설정하는 것이다.

실제 테스트에서도 같은 결과를 보여주었다.

php.net의 예제 소스들을 보면 stream_set_blocking또는 socket_set_blocking를 필히 false로 설정하라고 나와 있었지만,

이번의 경우에는 설정을 했을경우에 오히려 제대로 동작하지 않았다.

그 이유는 blocking모드를 false로 설정하게 되면 송수신이 완료하게 되었을 경우에만

데이터를 출력이나 socket의 상태값을 반환하기 때문이다.

timeout값을 설정한다고 해서 연결이 자동적으로 끊어지는것이 아니기 때문에

fget이나 feof등 의 데이터 수신 구문이 있는곳에는 필히

socket_get_status를 이용해서 수시로 연결 상태를 확인한후

timeout상태가 발생하면 예외 처리를 해주어야 한다.