在PHP中,利用Socket擴展,我們可以非常靈活地實現網絡通信功能,甚至可以用它來打造一個基本的網絡服務端。本文將重點講解如何使用socket_listen()和socket_accept()函數,構建一個簡單的TCP服務器。
socket_listen()
該函數用於監聽一個已經綁定了IP和端口的socket資源,等待客戶端連接請求。
socket_accept()
該函數用於接受一個進入的客戶端連接請求,並返回一個新的socket資源,用於與客戶端通信。
創建socket資源( socket_create )
綁定IP和端口( socket_bind )
監聽端口( socket_listen )
循環等待並接受客戶端連接( socket_accept )
讀寫數據,完成通信
關閉客戶端和服務器端socket
<?php
// 創建TCP socket(AF_INET協議族,流式傳輸)
$server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($server === false) {
die("socket_create() 失敗: " . socket_strerror(socket_last_error()) . "\n");
}
// 綁定IP和端口
$address = '0.0.0.0'; // 監聽所有網絡接口
$port = 8080;
if (!socket_bind($server, $address, $port)) {
die("socket_bind() 失敗: " . socket_strerror(socket_last_error($server)) . "\n");
}
// 開始監聽,允許等待連接的隊列長度為5
if (!socket_listen($server, 5)) {
die("socket_listen() 失敗: " . socket_strerror(socket_last_error($server)) . "\n");
}
echo "服務器已啟動,監聽 {$address}:{$port}\n";
while (true) {
// 阻塞等待客戶端連接
$client = socket_accept($server);
if ($client === false) {
echo "socket_accept() 失敗: " . socket_strerror(socket_last_error($server)) . "\n";
continue;
}
// 從客戶端讀取數據,最多讀取1024位元組
$input = socket_read($client, 1024);
if ($input === false) {
echo "socket_read() 失敗: " . socket_strerror(socket_last_error($client)) . "\n";
socket_close($client);
continue;
}
echo "收到客戶端數據: $input\n";
// 處理數據 - 這裡簡單回复客戶端一個消息
$response = "你好,客戶端!你發送的數據是:" . trim($input) . "\n";
socket_write($client, $response, strlen($response));
// 关闭客戶端连接
socket_close($client);
}
// 關閉服務器socket(一般不會走到這裡)
socket_close($server);
?>
在實際使用中,你可以根據需求對讀寫邏輯進行擴展,比如實現一個完整的協議解析器,或者異步處理多個客戶端。
監聽的IP可以設置為具體的地址,或使用'0.0.0.0'監聽所有可用網絡接口。
端口號應避免使用系統保留端口,一般選擇1024以上的端口。
以上代碼是一個同步阻塞的單線程服務端,適合入門理解。
通過socket_listen()和socket_accept() ,PHP能夠非常直接地搭建TCP服務端程序,實現基礎的網絡通信功能。雖然PHP不是專門為高性能服務器設計的語言,但用它快速原型開發小型服務,或者做一些簡單的網絡交互應用,依然非常實用。