현재 위치: > 최신 기사 목록> PHP에서 Stream_Socket_Shutdown을 호출하면 연결 예외가 중단됩니다. 그것을 피하고 수리하는 방법?

PHP에서 Stream_Socket_Shutdown을 호출하면 연결 예외가 중단됩니다. 그것을 피하고 수리하는 방법?

M66 2025-06-22

PHP 네트워크 프로그래밍에서 stream_socket_shutdown 함수는 소켓 연결의 특정 방향 (읽기, 쓰기 또는 둘 다)을 닫는 데 사용됩니다. 그러나 실제로 사용하면 많은 개발자가 stream_socket_shutdown을 호출 한 후 비정상적인 연결 중단, 클라이언트 오류 및 데이터 손실과 같은 문제를 겪습니다. 이 기사는 Stream_Socket_Shutdown 의 작동 메커니즘을 깊이 분석하고 연결 예외의 원인을 탐색하며 피하고 수리하는 방법을 제공합니다.


1. Stream_Socket_Shutdown 의 기본 사용

stream_socket_shutdown 의 함수 정의는 다음과 같습니다.

 bool stream_socket_shutdown(resource $stream, int $how)
  • $ stream : 오픈 소켓 스트림 리소스.

  • $ 방법 : 방향을 닫고 가치를 가져옵니다.

    • stream_shut_rd (0) 읽기 방향을 닫습니다

    • stream_shut_wr (1) 쓰기 방향을 닫습니다

    • stream_shut_rdwr (2) 읽기 및 쓰기 방향을 끄십시오

예를 들어:

 $socket = stream_socket_client("tcp://m66.net:8080", $errno, $errstr, 30);
if (!$socket) {
    die("연결이 실패했습니다: $errstr ($errno)");
}

// 글쓰기 방향을 닫습니다,데이터가 더 이상 전송되지 않음을 나타냅니다
stream_socket_shutdown($socket, STREAM_SHUT_WR);

stream_socket_shutdown을 호출 한 후 소켓의 특정 방향이 닫히고 커널은 핀 패킷을 피어에게 전송하여 연결이 닫혀 있음을 나타냅니다.


2. 왜 ream_socket_shutdown을 호출하면 연결에 대한 예외가 발생합니까?

예외의 근본 원인은 stream_socket_shutdown을 사용할 때 클라이언트 또는 서버가 연결의 종료 신호를 올바르게 처리하지 않거나 마감 순서가 부적절하다는 것입니다. 구체적으로 다음과 같이 나타납니다.

  • 쓰기 방향을 미리 닫아 피어가 데이터 읽기를 마치지 않으면 연결을 연결 해제합니다.

  • 동시에 읽기 및 쓰기 방향이 꺼져 있지만 데이터가 읽히지 않아 데이터 손실이 발생합니다.

  • 쓰기 방향을 닫은 후, 나머지 데이터는 제 시간에 읽지 않아서 비정상적인 연결을 초래합니다.

  • 핀 패킷은 피어에 의해 처리되지 않으므로 타임 아웃 및 단절에 연결됩니다 .

이러한 문제는 특히 TCP 긴 연결 또는 반이중 통신 시나리오에서 발생하기 쉽습니다.


3. Stream_Socket_Shutdown을 피하는 방법 예외 인터럽트를 유발하는 방법은 무엇입니까?

3.1 합리적으로 마감 방향을 선택하십시오

데이터를 보내고 다시 작성하려는 경우 전화하십시오.

 stream_socket_shutdown($socket, STREAM_SHUT_WR);

이는 쓰기 방향이 닫혀 있음을 의미하지만 동료가 전송하는 데이터를 기다리며 읽기 방향이 여전히 유지됩니다.

서버와 클라이언트가 먼저 쓰기 방향을 끄야하는 경우 피어가 나머지 데이터를 읽을 시간이 충분해야합니다.

3.2 글쓰기 방향을 닫은 후 데이터를 계속 읽으십시오.

쓰기 방향을 닫은 후에는 연결이 여전히 데이터를 읽을 수 있습니다. 일반적인 접근법은 다음과 같습니다.

 // 글쓰기 방향을 닫습니다
stream_socket_shutdown($socket, STREAM_SHUT_WR);

// 계속해서 피어 데이터를 계속 읽으십시오EOF
while (!feof($socket)) {
    $data = fread($socket, 8192);
    if ($data === false) {
        break;
    }
    // 처리 데이터
}

레거시 데이터를 읽지 않도록하십시오.

3.3 연결 종료 순서가 올바른지 확인하십시오

  • 먼저 쓰기 방향을 닫고 전송 될 피어 데이터를 알립니다.

  • 피어가 반환 할 수있는 데이터를 읽으십시오.

  • 읽은 후 읽기 방향을 닫거나 전체 연결을 닫으십시오.

3.4 합리적인 시간 초과 및 예외 캡처를 설정하십시오

Stream_set_timeout을 사용하여 읽기 및 쓰기 시간 초과를 설정하여 연결이 중단되는 차단을 피하십시오.


4. 연결 예외를위한 공통 수정의 예

다음 예제는 서버에 안전한 연결을 작성하는 올바른 방법을 보여줍니다.

 $server = stream_socket_server("tcp://0.0.0.0:12345", $errno, $errstr);
if (!$server) {
    die("서버를 시작할 수 없습니다: $errstr ($errno)");
}

$client = stream_socket_accept($server);
if ($client) {
    // 응답 데이터를 보냅니다
    fwrite($client, "Hello from server\n");

    // 글쓰기 방향을 닫습니다,클라이언트에게 더 이상 데이터가 없음을 알리십시오
    stream_socket_shutdown($client, STREAM_SHUT_WR);

    // 클라이언트가 보낸 데이터를 계속 읽으십시오
    while (!feof($client)) {
        $data = fread($client, 8192);
        if ($data === false || $data === "") {
            break;
        }
        echo "클라이언트 데이터를 받았습니다: $data\n";
    }

    // 연결을 닫으십시오
    fclose($client);
}

fclose($server);

5. 다른 예방 조치

  • 커뮤니케이션이 더 이상 수행되지 않는 한 읽기 및 쓰기 방향을 동시에 쓰지 마십시오.

  • 긴 연결을 위해 Stream_Socket_Shutdown에 대한 빈번한 호출을 피하고 하트 비트 패키지와 시간 초과 감지를 합리적으로 사용하십시오.

  • 클라이언트와 서버의 프로토콜 설계가 연결 타이밍 및 순서 폐쇄에 대해 명확하게 확인하십시오.

  • Blocking을 방지하려면 stream_set_blockingstream_set_timeout을 사용하십시오.


요약

Stream_Socket_Shutdown 은 소켓 연결을 닫는 데 중요한 도구이지만 부적절한 사용은 쉽게 비정상적인 연결 중단으로 이어질 수 있습니다. 폐쇄의 의미를 이해하고, 마감 방향을 합리적으로 선택하고, 마감 후 데이터의 읽기 및 쓰기 순서를 보장하는 것이 문제를 피하고 수정하는 데 핵심입니다. 올바른 시간 초과 설정과 예외 처리를 결합하면 PHP 네트워크 프로그램이보다 안정적이고 신뢰할 수 있습니다.