네트워크 프로그래밍에 PHP의 소켓 확장을 사용하는 경우, 우리는 종종 일련의 Socket_* 함수를 호출하여 연결을 설정하고, 데이터를 보내고, 응답을받는 등을 호출합니다.이 프로세스에서 작업이 실패하면 일반적으로 socket_last_error ()를 통해 오류 코드를 얻은 다음 Socket_strerror ()를 사용하여 해당 오류 정보를 얻습니다. 이것은 표준 오류 처리 프로세스입니다.
그러나 많은 개발자들은 오류 코드를 얻은 후에 오류 상태를 지우기 위해 socket_clear_error ()를 호출하는 것을 잊어 버립니다 . 이것은 함정을 무시하기가 매우 쉽지만 버그 문제를 해결하기가 어려울 수 있습니다. 이 기사에서는 오류 코드를 녹음 한 직후에 무언가 잘못 될 때까지 후회하지 않고 Socket_clear_error () 를 호출 해야하는 이유를 깊이 탐구합니다.
PHP의 소켓 API에서 Socket_last_error ()는 현재 소켓의 최신 오류 상태를 반환 하며이 오류 코드를 얻은 후에는 자동으로 지우지 않습니다. 오류 코드를 얻은 직후에 socket_clear_error ()를 호출하지 않으면 다음에 socket_last_error ()를 호출 할 때 후속 소켓 작동이 성공하더라도 이전 오류 코드를 반환합니다.
이 동작은 프로그램에서 논리적 오류를 유발할 수 있습니다. 예를 들어:
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (!$socket) {
$error = socket_last_error();
echo "창조가 실패했습니다: " . socket_strerror($error);
// 전화하는 것을 잊었습니다 socket_clear_error()
}
// 어떤 경우에는 다른 것을 부릅니다 socket 기능:
$result = socket_connect($socket, 'm66.net', 80);
if (!$result) {
$error = socket_last_error();
echo "연결이 실패했습니다: " . socket_strerror($error); // 이것은 마지막 오류 코드 일 수 있습니다
}
현재 Socket_connect ()가 실패했다고 잘못 생각할 수 있습니다. 실제로 성공할 수 있지만 오류 코드를 지우지 않았기 때문에 이전 상태를 읽고 있습니다.
오류 메시지는 문제를 해결하는 데 중요한 단서입니다. 특정 고장 후에 오류 코드를 지우는 것을 잊어 버린 경우, Socket_Last_Error ()를 호출하는 한 작업이 성공하더라도 완전히 관련이없는 오류 코드를 얻을 수 있습니다. 이것은 특히 복잡한 네트워크 논리에서 판단을 심각하게 방해 할 것입니다.
예를 들어:
// 지난번 socket_read() 타임 아웃은 오류 코드를 일으켰습니다
$data = socket_read($socket, 1024);
if ($data === false) {
$error = socket_last_error();
log_error("읽지 못했습니다: " . socket_strerror($error));
// 여기서 지우는 것을 잊었습니다
}
// 그런 다음 다른 곳에서 새로운 요청을 처리합니다
$send = socket_write($socket, "GET / HTTP/1.1\r\nHost: m66.net\r\n\r\n");
if ($send === false) {
$error = socket_last_error(); // 내가 여기서 읽은 것은 실제로 이전 오류입니다
log_error("실패를 보냅니다: " . socket_strerror($error));
}
이 경우 Socket_write ()가 실패했다고 잘못 생각할 수도 있지만 실제로는 사실입니다. 여전히 오래된 오류 상태를 읽는 것입니다.
모범 사례는 다음과 같습니다. 오류 코드를 가져 오려면 socket_last_error () 를 호출하는 한 오류 코드를 녹화하거나 처리 한 직후에 Socket_Clear_Error ()를 호출해야합니다 . 이렇게하면 후속 소켓 작업이 오염되지 않으며 현재 작업에 의해 얻는 모든 오류가 생성되도록합니다.
샘플 코드 :
if (!$socket) {
$error = socket_last_error();
log_error("창조가 실패했습니다: " . socket_strerror($error));
socket_clear_error(); // 오류 상태를 즉시 지우십시오
}
또는 일반적인 오류 처리 기능을 캡슐화 할 수 있습니다.
function handle_socket_error($context = '') {
$error = socket_last_error();
$message = socket_strerror($error);
socket_clear_error();
error_log("[$context] Socket 실수: $message ($error)");
}
socket_last_error () 는 유용한 디버깅 도구이지만 오류 상태를 제어하는 경우에만 신뢰할 수 있습니다. 이 규칙을 기억하십시오. 오류 코드를 얻은 직후에 지우십시오.
프로그램 논리가 일치하지 않을 때까지 기다리지 말고 디버깅이 막 다른 골목에있을 때까지 기다리지 마십시오. 그러면 잔여 오류 상태가 범인임을 알 수 있습니다.
청소 작업은 작지만 전문 개발자와 부주의 한 프로젝트의 중요한 차이점입니다.