PHP에서 네트워크 소켓을 작동 할 때 오류 처리는 항상 두통이었습니다. PHP는 함수 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 () 에 대한 후속 호출은 이전 오류 코드를 반환하여 논리적 판단에 혼란을 일으킬 수 있습니다.
비 블로킹 모드에서는 소켓 작동이 완료되기를 기다리지 않으며 때로는 오류 코드 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;
}
오랫동안 소켓 연결은 여러 번 임시 오류가 발생할 수 있습니다. 이전 오류 상태로 인해 후속 작업이 실패하지 않도록하기 위해 작업이 완료된 후 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 () 의 역할과 사용이 명확합니다. 비 차단, 긴 연결 및 기타 시나리오에서 적시에 오류 상태를 정리하여 소켓 프로그램을보다 강력하게 만들 수 있습니다.