PHP에서 네트워크 프로그래밍에 소켓을 사용하는 경우 Socket_set_block () 및 Socket_set_nonBlock () 은 각각 차단 모드와 비 블로킹 모드로 들어가기 위해 소켓을 제어하는 두 가지 매우 중요한 기능입니다. 그러나 많은 개발자들은 차단 모드로 설정 한 후 핵심 포인트를 무시합니다.
그런 다음 질문은 Socket_set_block ()을 사용하지만 타임 아웃을 설정하는 것을 잊어 버리면 어떻게됩니까? 프로그램이 고정 될까요? 이 기사는이 질문에 자세히 답변 할 것입니다.
Socket_set_block ($ socket)을 사용하여 소켓을 차단 모드로 설정하고 후속 읽기 및 쓰기 작업 (예 : Socket_read () , Socket_recv () , Socket_write () 등)가 차단하고 데이터가 준비되지 않은 경우 대기합니다. 즉, 데이터없이 소켓을 읽으려고하면 데이터가 읽을 수 있거나 연결이 연결이 끊어 질 때까지 해당 코드 줄에서 프로그램이 중지 됩니다.
이것은 "동시 커뮤니케이션"이 예상되는 일부 시나리오에서 유용합니다. 그러나 외부 서버가 천천히 또는 영구적으로 응답하지 않으면 (예 : 대상 서버 다운 타임, 네트워크 차단, 방화벽 차단 등) 프로그램이 고정되어 후속 코드를 실행할 수 없습니다 .
예를 살펴 보겠습니다.
<code> $ socket = socket_create (af_inet, sock_stream, sol_tcp); socket_set_block ($ socket); socket_connect ($ socket, 'gitbox.net', 80); socket_write ($ socket, "get / http / 1.0 \ r \ nhost : gitbox.net \ r \ n \ r \ n"); $ response = socket_read ($ socket, 2048);
에코 $ 응답;
</코드>
gitbox.net 이 도달 할 수 없거나 데이터를 전혀 반환하지 않으면 Code Socket_read () 라인이 무기한으로 차단되고 프로그램이 "고정"됩니다.
"고정"의 근본 원인은 시간 초과 제한 설정이 없기 때문입니다. 차단 모드 자체는 문제가되지 않습니다. 문제는 socket_set_option () 의 시간 초과 값이 설정되지 않았다는 것입니다.
PHP는 두 가지 소켓 타임 아웃 설정을 제공합니다.
시간 초과를 받으십시오
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, ['sec'=>5, 'usec'=>0]);
시간 초과를 보내십시오
socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, ['sec'=>5, 'usec'=>0]);
이를 추가 한 후에도 차단 모드에서도 읽기 및 쓰기 작업은 무기한 대기하지 않습니다. 예를 들어, 수신 시간 초과는 5 초로 설정됩니다. 5 초 이내에 데이터가 수신되지 않으면 Socket_read ()는 False를 반환하고 영원히 차단하지 않습니다.
타임 아웃을 설정하는 것을 잊어 버린 경우 몇 가지 잠재적 인 결과가 있습니다.
서버가 응답하지 않거나 느리면 갇혀 있습니다.
사용자는 너무 오래 기다리고 경험이 매우 열악합니다.
배치 작업의 막힘은 전체 작업이 대기열 또는 방해를 초래합니다.
특히 버그가 네트워크가 불안정 할 때만 발생하는 경우 문제를 해결하기가 어렵습니다.
따라서 차단 모드의 모든 네트워크 작동은 명확한 시간 초과 설정과 함께 사용해야합니다 .
예, socket_set_block ()을 사용하고 타임 아웃을 설정하는 것을 잊어 버리면 프로그램이 실제로 "부드러워 질 수 있습니다". 이것은 PHP의 버그가 아니라 네트워크 프로그래밍에서 I/O를 차단하는 기본 동작입니다. Socket_set_option () 의 시간 초과를 설정하는 데 합리적으로 사용하는 것이 프로그램 견고성 및 응답 성을 보장하는 핵심입니다.
모범 사례는 다음과 같습니다. 차단 모드로 들어가는 한 시간 초과를 즉시 설정하고 원격 서버의 안정성에 의존하지 않습니다. 이것은 방어 프로그래밍의 기본적인 생각입니다.