PHP에서 소켓 프로그래밍을 사용하는 경우 Socket_set_Block 함수는 일반적으로 소켓을 차단 모드로 설정하는 데 사용됩니다. 후속 읽기 및 쓰기 작업은 계속 실행되기 전에 데이터 완료를 "대기"할 수있을 것으로 예상됩니다. 그러나 많은 개발자들이 문제를 일으킬 것입니다. socket_set_block을 호출 한 후에는 프로그램이 여전히 차단되지 않은 것으로 보이며 읽기 및 쓰기 작업은 대기하지 않지만 즉시 돌아갑니다. 이게 왜? 이 기사는 그에 따른 이유를 깊이 분석하고 해당 솔루션을 제공합니다.
socket_set_block 의 기능은 소켓을 차단 모드로 설정하는 것입니다. 기능 서명은 다음과 같습니다.
bool socket_set_block ( resource $socket )
통화가 성공하면 true를 반환하십시오. 그렇지 않으면 False를 반환하십시오.
그러나 주목하는 것이 중요합니다.
Socket_set_Block 은 기본 소켓 자원에 대한 차단 모드이며 그 효과는 소켓의 특정 상태에 따라 다릅니다.
소켓이 이미 비 블로킹 모드 인 경우 (예 : socket_set_nonblock이 이전에 호출 되었음) socket_set_block을 호출 한 후 차단을 재개해야합니다.
그러나 소켓 자체가 특수 상태 (예 : 이미 연결된 상태 또는 일부 시스템 기본 상태) 인 경우 차단 모드를 설정하는 것이 적용되지 않을 수 있습니다.
기본 소켓은 다른 코드로 차단 상태로 재설정됩니다.
프로그램에는 소켓 설정과 충돌하는 다른 코드 또는 프레임 워크가있을 수 있습니다. 예를 들어, socket_set_block을 호출하기 전에 일부 라이브러리 또는 미들웨어는 socket_set_nonblock을 호출 할 수 있으며 기본 시스템 호출조차 소켓 속성을 변경하여 후속 호출이 잘못되었습니다.
소켓 연결은 일부 비동기 또는 시간 초과 상태에 있습니다
일부 운영 체제 또는 PHP 버전에서는 소켓이 연결되어 있거나 타임 아웃이 발생하면 소켓의 차단 모드 설정이 적용되지 않을 수 있습니다. 예를 들어:
연결이 완료되지 않은 경우 읽기 및 쓰기 작업이 차단되지 않습니다.
비표준 소켓 유형 (예 : UNIX 도메인 소켓, SSL 소켓)은 차단 모드를 일관성있게 지원합니다.
PHP 버전 및 운영 체제 호환성 문제
PHP의 다른 버전은 소켓 함수의 기본 구현에서 다를 수 있습니다. 특히 Windows 및 Linux 플랫폼의 동작도 다릅니다.
잘못된 통화 순서
socket_set_block 이 먼저 호출되지만 차단/비 블로킹 상태를 설정하는 다른 기능이 나중에 호출되면 상태 전환이 유효하지 않습니다.
코드에 사용 된 기능 자체는 블로킹을하지 않도록 설계되었습니다.
예를 들어, socket_select를 사용하거나 비 블로킹 스트림 작동 기능을 사용하면 소켓이 차단 상태에 있더라도 프로그램의 성능에 영향을 미칩니다.
한 번만, 합리적인 위치에 전화하십시오.
소켓을 생성하고 성공적으로 연결 한 후 Socket_set_block을 호출해야하며, 후속 코드 가이 설정을 재정의하지 않도록해야합니다.
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, "gitbox.net", 80);
socket_set_block($socket);
오류 확인과 결합
함수 호출이 true가 반환되는지 확인하고 시스템 또는 소켓 오류가 있는지 확인하십시오.
if (!socket_set_block($socket)) {
$errorcode = socket_last_error($socket);
$errormsg = socket_strerror($errorcode);
echo "차단 설정이 실패했습니다: [$errorcode] $errormsg\n";
}
비 블로킹 기능을 사용하여 혼합하십시오
상태 혼동을 피하기 위해 socket_set_block 과 socket_set_nonblock을 혼합하지 마십시오.
대신 stream_set_blocking을 사용하는 것을 고려하십시오
PHP의 스트림 캡슐화 소켓을 사용하는 경우 Stream_set_blocking을 사용하여 차단 모드를 제어 할 수 있습니다.
$stream = stream_socket_client("tcp://gitbox.net:80", $errno, $errstr, 30);
stream_set_blocking($stream, true);
다음 예제는 차단 소켓을 올바르게 설정하고 HTTP 요청을 보내는 방법을 보여줍니다.
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
die("만들다Socket실패하다: " . socket_strerror(socket_last_error()) . "\n");
}
$result = socket_connect($socket, "gitbox.net", 80);
if ($result === false) {
die("连接실패하다: " . socket_strerror(socket_last_error($socket)) . "\n");
}
// 차단 모드를 설정하십시오
if (!socket_set_block($socket)) {
die("차단 설정이 실패했습니다: " . socket_strerror(socket_last_error($socket)) . "\n");
}
$request = "GET / HTTP/1.1\r\nHost: gitbox.net\r\nConnection: Close\r\n\r\n";
socket_write($socket, $request, strlen($request));
// 데이터를 읽을 때 차단합니다,내용이 수신되거나 연결이 닫힐 때까지
$response = '';
while ($out = socket_read($socket, 2048)) {
$response .= $out;
}
echo $response;
socket_close($socket);
Socket_set_block 의 기능은 소켓을 차단하도록 설정하는 것이지만 전능하지 않으며 소켓 자체, 운영 체제, PHP 버전 및 통화 순서와 같은 다양한 요인의 영향을받습니다.
socket_set_block 호출은 여전히 비 블로킹을 보여줍니다. 일반적으로 상태가 다른 코드로 덮여 있으므로 연결 상태는 특별하거나 기본 구현이 다릅니다.
올바른 접근 방식은 소켓의 차단 설정 프로세스를 엄격하게 제어하여 클릭과 비 블로킹 설정 기능을 혼합하지 않도록하는 것입니다.
기본 소켓과 PHP 환경의 차이점을 이해하고 디버그 정보 위치 문제를 결합하십시오.
이러한 주요 포인트를 마스터하면 PHP의 소켓 차단 동작을보다 안정적으로 제어하고 예상치 못한 비동기 성능을 피할 수 있습니다.