현재 위치: > 최신 기사 목록> 네트워크 애플리케이션 성능을 향상시키기 위해 PHP에서 소켓의 읽기 동작을 제어하는 ​​방법은 무엇입니까?

네트워크 애플리케이션 성능을 향상시키기 위해 PHP에서 소켓의 읽기 동작을 제어하는 ​​방법은 무엇입니까?

gitbox 2025-09-20
<span><span><span class="hljs-meta">&lt;?php</span></span><span>
</span><span><span class="hljs-comment">// 다음 내용은 기사의 본문과 관련이 없습니다.</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"여기 예입니다 PHP 암호,기사와 관련이없는 사문을 표시하는 데 사용됩니다.。\n"</span></span><span>;

-------------------------------------------------------------------------------

<span class="hljs-comment">/**
 * 통과하는 방법 stream_set_blocking 제어 PHP 소켓의 행동을 읽습니다,네트워크 응용 프로그램 성능을 향상시킵니다?
 *
 * 존재하다 PHP 네트워크 프로그래밍에서,소켓(socket)읽기 동작은 응용 프로그램 성능에 직접적인 영향을 미칩니다.。기본적으로,
 * PHP 的소켓操作是阻塞式的,즉, 읽기 기능을 호출 할 때(좋다 fread 또는 stream_get_contents)시간,
 * 좋다果没有数据到达,프로그램이 기다릴 것입니다,데이터를 사용할 수있을 때까지。这种行为존재하다高并发또는长连接场景下容易导致性能瓶颈。
 *
 * 이 문제를 해결합니다,PHP 제공 stream_set_blocking 기능,可以灵活地제어소켓的차단 모드。
 *
 * 하나、stream_set_blocking 기본 사용
 *
 * 기능原型:
 * bool stream_set_blocking ( resource $stream , int $mode )
 *
 * 매개 변수 설명:
 * - $stream: 소켓의지(stream 의지)。
 * - $mode: 차단 모드,1 차단을 나타냅니다(blocking),0 비 블로킹을 나타냅니다(non-blocking)。
 *
 * 예:
 */</span>
</span><span><span class="hljs-variable">$socket</span></span><span> = </span><span><span class="hljs-title function_ invoke__">stream_socket_client</span></span><span>(</span><span><span class="hljs-string">"tcp://127.0.0.1:8080"</span></span><span>, </span><span><span class="hljs-variable">$errno</span></span><span>, </span><span><span class="hljs-variable">$errstr</span></span><span>, </span><span><span class="hljs-number">30</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (!</span><span><span class="hljs-variable">$socket</span></span><span>) {
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"연결이 실패했습니다: <span class="hljs-subst">$errstr</span></span></span><span> (</span><span><span class="hljs-subst">$errno</span></span><span>)\n";
} </span><span><span class="hljs-keyword">else</span></span><span> {
    </span><span><span class="hljs-comment">// 设置非차단 모드</span></span><span>
    </span><span><span class="hljs-title function_ invoke__">stream_set_blocking</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, </span><span><span class="hljs-number">0</span></span><span>);
    
    </span><span><span class="hljs-comment">// 데이터를 읽으십시오</span></span><span>
    </span><span><span class="hljs-variable">$data</span></span><span> = </span><span><span class="hljs-title function_ invoke__">fread</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, </span><span><span class="hljs-number">8192</span></span><span>);
    </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$data</span></span><span> === </span><span><span class="hljs-literal">false</span></span><span>) {
        </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"현재 읽을 수있는 데이터가 없습니다,이 프로그램은 계속 실행됩니다。\n"</span></span><span>;
    } </span><span><span class="hljs-keyword">else</span></span><span> {
        </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"데이터를 읽습니다: <span class="hljs-subst">$data</span></span></span><span>\n";
    }
}
-------------------------------------------------------------------------------

<span class="hljs-comment">/**
 * 둘、차단 모드与非차단 모드的差异
 *
 * 1. 차단 모드(blocking)
 *    - fread 또는 fgets 돌아 오기 전에 데이터가 도착할 때까지 기다립니다。
 *    - 단일 스레드에 적합합니다、낮은 동시성 시나리오。
 *    - 단순한,但可能导致长시간间等待阻塞整个脚本。
 *
 * 2. 非차단 모드(non-blocking)
 *    - fread 等기능立即返回,若无数据则返回空또는 false。
 *    - 비동기 처리에 적합합니다、높은 동시성 시나리오。
 *    - 결합 할 수 있습니다 stream_select 监控多个소켓的可读状态,이것은 네트워크 응용 프로그램 성능을 향상시킵니다。
 *
 * 삼、결합 stream_select 성능 향상
 *
 * stream_select 여러 개의 스트림을 읽을 수 있는지 모니터링 할 수 있습니다、可写또는发生异常:
 *
 * 예:
 */</span>
</span><span><span class="hljs-variable">$read</span></span><span> = [</span><span><span class="hljs-variable">$socket</span></span><span>];
</span><span><span class="hljs-variable">$write</span></span><span> = </span><span><span class="hljs-literal">null</span></span><span>;
</span><span><span class="hljs-variable">$except</span></span><span> = </span><span><span class="hljs-literal">null</span></span><span>;
</span><span><span class="hljs-variable">$timeout</span></span><span> = </span><span><span class="hljs-number">2</span></span><span>; </span><span><span class="hljs-comment">// 超시간시간间 2 두번째</span></span><span>

</span><span><span class="hljs-variable">$num_changed_streams</span></span><span> = </span><span><span class="hljs-title function_ invoke__">stream_select</span></span><span>(</span><span><span class="hljs-variable">$read</span></span><span>, </span><span><span class="hljs-variable">$write</span></span><span>, </span><span><span class="hljs-variable">$except</span></span><span>, </span><span><span class="hljs-variable">$timeout</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$num_changed_streams</span></span><span> === </span><span><span class="hljs-literal">false</span></span><span>) {
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"监控소켓出错\n"</span></span><span>;
} </span><span><span class="hljs-keyword">elseif</span></span><span> (</span><span><span class="hljs-variable">$num_changed_streams</span></span><span> === </span><span><span class="hljs-number">0</span></span><span>) {
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"超시간,아직 읽을 수있는 데이터가 없습니다\n"</span></span><span>;
} </span><span><span class="hljs-keyword">else</span></span><span> {
    </span><span><span class="hljs-keyword">foreach</span></span><span> (</span><span><span class="hljs-variable">$read</span></span><span> </span><span><span class="hljs-keyword">as</span></span><span> </span><span><span class="hljs-variable">$r</span></span><span>) {
        </span><span><span class="hljs-variable">$data</span></span><span> = </span><span><span class="hljs-title function_ invoke__">fread</span></span><span>(</span><span><span class="hljs-variable">$r</span></span><span>, </span><span><span class="hljs-number">8192</span></span><span>);
        </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"수신 데이터: <span class="hljs-subst">$data</span></span></span><span>\n";
    }
}
-------------------------------------------------------------------------------

<span class="hljs-comment">/**
 * 네、실제 응용 프로그램의 성능 최적화 제안
 *
 * 1. 존재하다高并发网络应用中,尽量사용非차단 모드读取소켓,단일 느린 연결로 전체 프로세스 차단을 피하십시오.。
 * 2. 사용 stream_select 또는类似事件循环机制(좋다 ReactPHP)来轮询多个소켓。
 * 3. 긴 연결을 위해,合理设置读取超시간시간间,무한한 막힘을 피하십시오。
 * 4. 避免존재하다차단 모드下处理大量数据,必要시간可分块读取또는사용缓冲。
 *
 * 通过合理사용 stream_set_blocking 이벤트 루프 메커니즘,크게 향상 될 수 있습니다 PHP 네트워크 응용 프로그램의 응답 속도 및 처리량。
 */</span>
</span><span><span class="hljs-meta">?&gt;</span></span><span>
</span></span>