當前位置: 首頁> 最新文章列表> socket_set_block 與stream_set_blocking 有何不同?

socket_set_block 與stream_set_blocking 有何不同?

gitbox 2025-05-26

在PHP中,處理網絡通信時,阻塞與非阻塞模式的控制非常重要。 socket_set_blockstream_set_blocking是兩個常用的函數,它們都用於設置套接字或流的阻塞行為,但適用的對象和用法上有些區別。本文將詳細介紹這兩個函數的差異及其使用方法。

一、基本概念

  • 阻塞模式(Blocking Mode) :函數調用會等待操作完成,比如讀取數據直到有數據可讀,寫入數據直到發送完成,期間程序會暫停等待。

  • 非阻塞模式(Non-blocking Mode) :函數調用不會等待操作完成,如果操作無法立刻完成,會立即返回,程序可以繼續執行其他任務。

二、函數介紹

1. socket_set_block

  • 適用於: PHP Socket 擴展中的socket 資源(通過socket_create()等函數創建)

  • 作用:設置套接字為阻塞模式。

  • 函數原型:

     bool socket_set_block(resource $socket)
    
  • 返回值:成功返回true ,失敗返回false

2. stream_set_blocking

  • 適用於:基於流的資源,如fopen()stream_socket_client()返回的資源,或者socket_create()的資源通過socket_import_stream()轉換後的流資源。

  • 作用:設置流的阻塞模式。

  • 函數原型:

     bool stream_set_blocking(resource $stream, int $mode)
    
  • 參數:

    • $stream :流資源

    • $mode :1表示阻塞,0表示非阻塞

  • 返回值:成功返回true ,失敗返回false

三、主要區別

特性socket_set_block stream_set_blocking
適用資源Socket擴展中的socket 資源PHP流資源(文件流、網絡流等)
阻塞模式設置方法直接調用,無需額外參數通過第二個參數(0或1)指定阻塞模式
用法靈活度只能設置阻塞,非阻塞需用socket_set_nonblock()可設置阻塞或非阻塞
適用場景低層套接字編程高層網絡流編程

四、示例代碼

1. 使用socket_set_block

 <?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
    die("socket_create failed: " . socket_strerror(socket_last_error()));
}

socket_set_block($socket); // 設置為阻塞模式

// 連接服務器
socket_connect($socket, "gitbox.net", 80);

// 發送請求
$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);
?>

2. 使用stream_set_blocking

 <?php
$stream = stream_socket_client("tcp://gitbox.net:80", $errno, $errstr, 30);
if (!$stream) {
    die("Connection failed: $errstr ($errno)");
}

// 設置為阻塞模式
stream_set_blocking($stream, 1);

// 發送請求
fwrite($stream, "GET / HTTP/1.1\r\nHost: gitbox.net\r\nConnection: Close\r\n\r\n");

// 讀取響應
$response = '';
while (!feof($stream)) {
    $response .= fread($stream, 2048);
}

echo $response;

fclose($stream);
?>

五、總結

  • socket_set_block專門用於PHP的Socket擴展中socket資源,直接將套接字設置為阻塞狀態。

  • stream_set_blocking適用於更廣泛的流資源,且可以靈活切換阻塞和非阻塞模式。

  • 選擇哪個函數主要看你用的資源類型:如果用Socket擴展管理socket,就用socket_set_block ;如果用流資源(如stream_socket_client ),則用stream_set_blocking

了解這兩個函數及其區別,有助於你在PHP網絡編程中更好地控制數據讀寫行為,優化程序性能與響應。