현재 위치: > 최신 기사 목록> 공식 PHP 문서에 누락 된 Socket_clear_error () 장면 보충제

공식 PHP 문서에 누락 된 Socket_clear_error () 장면 보충제

M66 2025-06-02

PHP에서 네트워크 소켓을 작동 할 때 오류 처리는 항상 두통이었습니다. PHP는 함수 Socket_clear_Error () 를 제공하지만 공식 문서는 사용 시나리오를 매우 짧게 설명하므로 많은 개발자 가이 기능을 사용할 때 불분명하게 만듭니다.

이 기사는 실제 사례를 결합하여 Socket_clear_Error () 의 적용 가능한 시나리오를 분류하고 소켓 오류를보다 우아하게 처리하는 방법에 대한 예를 제공합니다.


socket_clear_error () 란?

Socket_clear_error () 는 현재 소켓 연결 오류 상태를 정리하는 데 특별히 사용되는 PHP의 소켓 확장 기능입니다. 간단히 말해서 소켓 연결의 오류 플래그를 "재설정"할 수 있습니다.

공식 문서에서 socket_clear_error ()는 함수 서명과 문장 설명 만 씁니다.

 bool socket_clear_error ( resource $socket )

소켓 오류 상태를 지우십시오.

그러나 호출 해야하는시기 또는 어떤 영향을 미칠지 명시하지 않습니다.


소켓 오류를 정리하는 이유는 무엇입니까?

네트워크 전송 프로세스 중에는 단절, 데이터 전송 실패 및 네트워크 차단과 같은 다양한 오류가 발생할 수 있습니다. PHP의 소켓 함수는 일반적으로 False를 반환하고 오류 코드를 설정합니다. Socket_last_error ()를 사용하여 오류 코드를 가져온 다음 Socket_strerror ()를 사용하여 읽을 수있는 정보로 변환합니다.

그러나 이러한 오류 메시지는 수동으로 정리 될 때까지 "계속"됩니다. 그렇지 않으면 후속 소켓 작업은 이전 오류의 영향을받을 수있어 잘못 판단됩니다.

간단한 예를 들기 위해 :

 $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, 'm66.net', 80);
socket_write($socket, "GET / HTTP/1.1\r\nHost: m66.net\r\n\r\n");

$errorCode = socket_last_error($socket);
if ($errorCode !== 0) {
    echo "오류가 발생했습니다:" . socket_strerror($errorCode) . PHP_EOL;
    socket_clear_error($socket); // 오류 상태를 정리하십시오,후속 작업에 영향을 미치지 마십시오
}

// 계속 사용하십시오 $socket 다른 일을하십시오

socket_clear_error ()가 호출되지 않으면 Socket_last_error () 에 대한 후속 호출은 이전 오류 코드를 반환하여 논리적 판단에 혼란을 일으킬 수 있습니다.


일반적인 사용 시나리오

1. 비 차단 소켓을 읽고 쓸 때

비 블로킹 모드에서는 소켓 작동이 완료되기를 기다리지 않으며 때로는 오류 코드 eagain 또는 ewouldBlock이 반환되어 데이터를 일시적으로 사용할 수 없음을 나타냅니다. 이 오류는 실제 실패가 아니며 프로그램에 나중에 다시 시도하도록 지시합니다.

오류 상태가 정리되지 않으면 프로그램은 연결에 문제가 있다고 잘못 생각하여 연결이 사전에 닫히도록합니다.

 socket_set_nonblock($socket);

while (true) {
    $data = socket_read($socket, 2048);
    if ($data === false) {
        $err = socket_last_error($socket);
        if ($err === SOCKET_EAGAIN || $err === SOCKET_EWOULDBLOCK) {
            socket_clear_error($socket);
            // 현재 데이터가 없습니다,나중에 다시 시도하십시오
            usleep(100000);
            continue;
        } else {
            // 다른 오류,처리 또는 종료
            break;
        }
    }
    echo $data;
}

2. 연결 다중화 또는 긴 연결 오류 정리

오랫동안 소켓 연결은 여러 번 임시 오류가 발생할 수 있습니다. 이전 오류 상태로 인해 후속 작업이 실패하지 않도록하기 위해 작업이 완료된 후 Socket_Clear_Error ()를 호출하는 것이 좋습니다.


요약

  • socket_clear_error () 는 소켓의 현재 오류 상태를 정리하는 기능입니다.

  • 임시 이용 불가능 (eagain/ewouldBlock)으로 인한 잘못 판단을 피하기 위해 비 차단 소켓 프로그래밍에 종종 사용됩니다.

  • 멀티플렉싱 또는 긴 연결 시나리오와 관련하여 오류 상태가 재설정되고 후속 작업이 정상인지 확인하는 데 사용될 수도 있습니다.

  • 호출되지 않으면 오류 상태가 유지되어 Socket_last_error ()가 만료 된 오류 코드를 반환하여 비즈니스 로직에 영향을 미칩니다.


참조 샘플 코드

 <?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (!$socket) {
    die("만들 수 없습니다 socket: " . socket_strerror(socket_last_error()) . PHP_EOL);
}

if (!socket_connect($socket, 'm66.net', 80)) {
    die("연결이 실패했습니다: " . socket_strerror(socket_last_error($socket)) . PHP_EOL);
}

socket_set_nonblock($socket);

$request = "GET / HTTP/1.1\r\nHost: m66.net\r\nConnection: close\r\n\r\n";
socket_write($socket, $request);

while (true) {
    $data = socket_read($socket, 2048);
    if ($data === false) {
        $err = socket_last_error($socket);
        if ($err === SOCKET_EAGAIN || $err === SOCKET_EWOULDBLOCK) {
            socket_clear_error($socket);
            usleep(100000); // 기다리다 0.1 몇 초 만에 다시 읽으십시오
            continue;
        } else {
            echo "오류를 읽으십시오:" . socket_strerror($err) . PHP_EOL;
            break;
        }
    } elseif ($data === '') {
        // 연결이 닫힙니다
        break;
    }
    echo $data;
}

socket_close($socket);

이 코드는 소시 _clear_error ()를 사용하여 비 블로킹 모드에서 임시 데이터가없는 오류를 무시하고 HTTP 응답을 성공적으로 읽는 방법을 보여줍니다.


이러한 방식으로 Socket_clear_error () 의 역할과 사용이 명확합니다. 비 차단, 긴 연결 및 기타 시나리오에서 적시에 오류 상태를 정리하여 소켓 프로그램을보다 강력하게 만들 수 있습니다.