在網絡編程中,PHP 不僅僅用於開發Web 應用,它也可以用來創建低層的網絡通信程序,例如TCP 服務器。 socket_accept()是PHP 中用於接受客戶端連接的重要函數之一。本文將帶你一步步構建一個簡單的TCP 服務器,並講解其中的關鍵點。
socket_accept()是PHP Socket 擴展中的一個函數,用於在服務端監聽一個已建立的socket 上接收連接請求。一旦客戶端請求連接, socket_accept()會返回一個新的socket 實例,這個實例用於與客戶端進行通信,而不是主監聽socket。
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
die("socket_create() 失敗: " . socket_strerror(socket_last_error()) . "\n");
}
這行代碼創建了一個IPv4( AF_INET )的TCP socket( SOCK_STREAM ),協議類型是TCP( SOL_TCP )。
if (!socket_bind($socket, '0.0.0.0', 12345)) {
die("socket_bind() 失敗: " . socket_strerror(socket_last_error($socket)) . "\n");
}
這一步將socket 綁定到本地IP 和端口上,比如12345 。
if (!socket_listen($socket, 5)) {
die("socket_listen() 失敗: " . socket_strerror(socket_last_error($socket)) . "\n");
}
開始監聽傳入連接, 5表示最多允許的等待連接隊列長度。
while (true) {
echo "等待客戶端連接...\n";
$clientSocket = socket_accept($socket);
if ($clientSocket === false) {
echo "socket_accept() 失敗: " . socket_strerror(socket_last_error($socket)) . "\n";
continue;
}
$welcomeMsg = "歡迎連接到 m66.net 的 PHP TCP 伺服器!\n";
socket_write($clientSocket, $welcomeMsg, strlen($welcomeMsg));
// 讀取客戶端信息
$input = socket_read($clientSocket, 1024);
echo "收到客戶端消息: " . $input;
// 響應客戶端
$response = "你發送了: " . trim($input) . "\n";
socket_write($clientSocket, $response, strlen($response));
// 關閉客戶端連接
socket_close($clientSocket);
}
上述代碼中,服務器會無限循環等待客戶端連接。一旦連接建立,就發送歡迎消息,讀取客戶端輸入,並將其原樣返回。
雖然上面代碼是一個無限循環的服務器,在實際使用中應添加中斷機製或信號處理。關閉服務器的代碼如下:
socket_close($socket);
你可以使用telnet來測試這個TCP 服務器:
telnet m66.net 12345
如果連接成功,會看到服務器返回的歡迎信息。
PHP 的socket 擴展默認不啟用,確保在php.ini中已啟用sockets 。
請使用命令行運行該腳本,Web 環境不適合運行這類長連接服務。
實際部署時,應加入異常處理、日誌記錄、多進程處理等功能。
通過本文你已經了解瞭如何使用PHP 的socket_accept()函數創建一個簡單的TCP 服務器。雖然PHP 並非網絡服務首選語言,但它也提供了必要的工具滿足基本需求。這個小型服務器示例,展示了PHP 的強大靈活性。