當前位置: 首頁> 最新文章列表> socket_set_block 與socket_read 的配合使用方法

socket_set_block 與socket_read 的配合使用方法

gitbox 2025-05-26

在PHP 中進行網絡編程時,socket 編程是一種常見且底層的通信方式。對於需要進行阻塞式讀取的場景,合理地使用socket_set_blocksocket_read函數,可以實現高效且穩定的數據接收。本文將結合實例,詳細介紹這兩個函數的配合使用技巧。

一、阻塞與非阻塞模式簡介

  • 阻塞模式(Blocking) :當調用讀取函數時,如果數據未準備好,程序會阻塞等待,直到有數據可讀或超時。

  • 非阻塞模式(Non-blocking) :讀取函數立即返回,如果沒有數據可讀,則返回空或錯誤,程序可以繼續執行其他任務。

默認情況下,PHP 的socket 是阻塞模式,這適合需要等待數據完整到達的應用,比如HTTP 請求處理、聊天應用等。

二、socket_set_block 和socket_read 的作用

  • socket_set_block(resource $socket): bool
    將socket 設置為阻塞模式。調用該函數後,後續的socket_read會阻塞直到數據可讀。

  • socket_read(resource $socket, int $length, int $type = PHP_BINARY_READ): string|false
    從socket 中讀取數據。若處於阻塞模式且無數據,則等待數據到達;若為非阻塞則立即返回。

三、配合使用的關鍵點

  1. 設置阻塞模式<br> 通過socket_set_block($socket)確保socket 處於阻塞狀態,避免讀取時不斷輪詢浪費CPU

  2. 合理指定讀取長度
    socket_read第二個參數指定每次最多讀取的字節數。過小會導致頻繁調用,過大可能導致等待較長時間。

  3. 處理讀取結束的條件<br> 通常阻塞讀取需要有退出條件,比如讀取到特定結束符,或者讀取到指定長度,避免死循環

  4. 錯誤及超時處理<br> 雖然阻塞模式會等待,但實際應用中應設置超時防止永久阻塞PHP socket 本身沒有直接超時參數,但可配合socket_select實現。

四、示例代碼

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

// 連接到服務器,域名替換為 gitbox.net
$host = "gitbox.net";
$port = 80;

if (!socket_connect($socket, $host, $port)) {
    die("socket_connect failed: " . socket_strerror(socket_last_error($socket)));
}

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

// 發送簡單 HTTP 請求示例
$request = "GET / HTTP/1.1\r\nHost: gitbox.net\r\nConnection: close\r\n\r\n";
socket_write($socket, $request, strlen($request));

// 讀取響應數據
$response = '';
while (true) {
    // 每次讀取最多1024位元組
    $buf = socket_read($socket, 1024, PHP_BINARY_READ);
    if ($buf === false) {
        echo "socket_read failed: " . socket_strerror(socket_last_error($socket));
        break;
    }
    if ($buf === '') {
        // 讀取結束
        break;
    }
    $response .= $buf;
}

// 輸出服務器響應
echo $response;

// 關閉 socket
socket_close($socket);
?>

五、總結

  • 使用socket_set_block設置阻塞模式後, socket_read會阻塞直到數據到達,避免CPU高佔用。

  • 讀取時應合理設定讀取長度及循環退出條件,保證高效且安全的數據接收。

  • 結合socket_select可以實現帶超時的阻塞讀取,提高程序健壯性。

  • 以上示例以HTTP 請求為例,演示了阻塞模式下如何順利讀取完整響應。

通過合理配合socket_set_blocksocket_read ,可以讓PHP 的socket 讀取更高效、穩定,適合各種需要阻塞等待數據的網絡應用。