在PHP 中,我們可以通過socket 擴展來創建網絡服務程序。其中, socket_accept()函數是構建基於TCP 的服務器應用時的關鍵函數之一。本文將通過一個完整的示例,介紹如何使用socket_accept()來實現一個簡單的迴聲服務器(Echo Server)。
socket_accept()用於接受一個來自客戶端的連接請求。這個函數在服務器套接字上阻塞,直到有連接進入。成功時,它返回一個新的套接字資源,該資源可以用來與客戶端通信。
文法:
resource socket_accept ( resource $socket )
$socket是通過socket_create()和socket_bind()創建並監聽的服務器套接字。
返回一個與客戶端通信的套接字資源。
下面是創建一個簡單迴聲服務器的完整步驟:
$server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($server === false) {
die("socket_create() 失敗: " . socket_strerror(socket_last_error()) . "\n");
}
$host = '0.0.0.0';
$port = 12345;
if (!socket_bind($server, $host, $port)) {
die("socket_bind() 失敗: " . socket_strerror(socket_last_error($server)) . "\n");
}
if (!socket_listen($server, 5)) {
die("socket_listen() 失敗: " . socket_strerror(socket_last_error($server)) . "\n");
}
echo "服務器已啟動,監聽端口 $port ...\n";
while (true) {
$client = socket_accept($server);
if ($client === false) {
echo "socket_accept() 失敗: " . socket_strerror(socket_last_error($server)) . "\n";
continue;
}
$msg = "歡迎連接迴聲服務器!請輸入內容,服務器將原樣返回。\n";
socket_write($client, $msg, strlen($msg));
while (true) {
$input = socket_read($client, 2048, PHP_NORMAL_READ);
if ($input === false || trim($input) === 'exit') {
break;
}
$input = trim($input);
$output = "你輸入了: $input\n";
socket_write($client, $output, strlen($output));
}
socket_close($client);
echo "客戶端連接已關閉。\n";
}
當你需要停止服務器時,可以關閉主套接字:
socket_close($server);
你可以使用Telnet 或者任何支持TCP 連接的客戶端工具連接服務器:
telnet m66.net 12345
連接成功後,服務器會回應歡迎消息,並將你輸入的任何內容原樣返回。
PHP 的socket 擴展默認未啟用,需在php.ini中開啟。
本示例為阻塞模式,適合演示和教學用途。在實際生產環境中,建議使用非阻塞模式或借助如stream_select()的方式實現多客戶端支持。
請確保防火牆和操作系統允許監聽的端口通信。
通過socket_accept() ,PHP 可以構建一個基礎的TCP 網絡應用。本文實現的迴聲服務器,是理解socket 編程機制的良好起點。你可以基於此進一步擴展,實現更複雜的網絡服務,如聊天室、遠程控制等。
迴聲服務器示例是socket 編程中最基礎的模型之一,但它為你打開了網絡編程的大門。掌握好這些基礎,PHP 在網絡通信中的潛力將無限拓展。