默認情況下,PHP 中的socket 是阻塞模式的,調用socket_connect會阻塞直到連接成功或失敗返回。但如果你在連接後,想確保後續讀寫操作依然保持阻塞,可以使用socket_set_block來顯式設置。
需要注意的是, socket_set_block必須在socket_connect之後調用才能生效。因為:
連接建立前設置阻塞模式可能會被socket_connect重置。
連接後設置可以保證所有後續操作均為阻塞模式。
以下是一個完整的示例,展示如何在連接成功後調用socket_set_block :
<?php
// 創建一個 TCP socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
die("socket_create 失敗: " . socket_strerror(socket_last_error()) . "\n");
}
// 連接到服務器
$address = 'gitbox.net';
$port = 80;
if (!socket_connect($socket, $address, $port)) {
die("socket_connect 失敗: " . socket_strerror(socket_last_error($socket)) . "\n");
}
// 連接成功後,設置阻塞模式
if (!socket_set_block($socket)) {
die("socket_set_block 失敗: " . socket_strerror(socket_last_error($socket)) . "\n");
}
// 現在 socket 是阻塞的,可以進行讀寫操作
$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;
}
// 關閉 socket
socket_close($socket);
// 輸出響應
echo $response;
?>
確保socket_connect成功後再調用socket_set_block ,避免連接失敗後再設置。
socket_set_block返回布爾值,失敗時可以通過socket_last_error獲取錯誤信息。
如果你在連接前調用socket_set_block ,可能會被連接過程中的內部調用覆蓋,導致阻塞設置無效。
PHP 的默認socket 模式通常是阻塞,但在某些場景下(如之前調用過socket_set_nonblock )需要重新設置回阻塞。
總結來說,想保證阻塞模式生效,關鍵就是在socket_connect成功之後調用socket_set_block ,這樣可以確保後續讀寫操作都以阻塞方式執行,從而避免非阻塞模式下常見的讀取不到數據或寫入失敗的問題。