1. 程式人生 > >PHP中如何使用socket進行通訊?

PHP中如何使用socket進行通訊?

1. socket 概述 socket 也稱作套接字,用於描述 IP 地址和埠,是一個通訊鏈的控制代碼,可以用來實現不同計算機之間的通訊。socket 是對 TCP / IP 協議的封裝,它只是提供了一組針對 TCP 或者 UDP 進行程式設計的介面(API)。 socket 利用客戶端 / 伺服器端的模式巧妙地解決了程序之間建立通訊連線的問題。 2. socket 的工作原理 伺服器端先初始化 socket,然後與埠繫結(bind),對埠進行監聽(listen),等待客戶端連線,呼叫accept阻塞。 這時,如果有客戶端初始化一個 socket,然後請求連線伺服器(connect),如果連線成功,客戶端與伺服器端的連線就建立了。客戶端傳送資料請求,伺服器端接收請求並處理請求,然後把響應資料傳送給客戶端,客戶端讀取資料,最後關閉連線,一次互動結束。 3. socket通訊演示
伺服器端的程式碼: (在 E:\xampp\htdocs\demo 下新建一個php檔案socket_server.php) <?php // 設定指令碼最大執行時間,單位為秒,0表示永不超時 set_time_limit(0); $address = '127.0.0.1'; $port = 10005;   // 埠可以是1到65535之間的任何數字,前提是未被佔用 // 建立並返回一個套接字(通訊節點),一個典型的網路連線由 2 個套接字構成,一個執行在伺服器端,另一個執行在客戶端 if( ($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) { echo "socket_create() failed, reason: " . socket_strerror(socket_last_error()) . "\n"; } // 繫結socket到具體的主機埠 if (socket_bind($sock, $address, $port) === false) { echo "socket_bind() failed, reason: " . socket_strerror(socket_last_error($sock)) . "\n"; } // 監聽socket伺服器上的請求連線,等待接入 if (socket_listen($sock, 5) === false) { echo "socket_listen() failed, reason: " . socket_strerror(socket_last_error($sock)) . "\n"; } do { // 確認客戶端的連線請求,成功後,返回一個新的子socket控制代碼(子執行緒),用於通訊 if (($msgsock = socket_accept($sock)) === false) { echo "socket_accept() failed, reason: ".socket_strerror(socket_last_error($sock)) . "\n"; break; } $msg = "Welcome to connect '$address'"."\n"; // 傳送訊息(資料)到客戶端 if (false === socket_write($msgsock, $msg, strlen($msg))){ echo "socket_write() failed, reason: " . socket_strerror(socket_last_error($sock)) ."\n"; } echo "Read client message \n"; // 讀取客戶端的資料 $receivedData = socket_read($msgsock, 8192); echo "Received message: ".$receivedData."\n";; // 將客戶端發來的資料,進行處理,然後再發送資料給客戶端 $responseData = '[time:'.date('Y-m-d H:i:s').']'.PHP_EOL.'[data:'.trim($receivedData).']'; if (false === socket_write($msgsock, $responseData, strlen($responseData))) {   echo "socket_write() failed, reason: " . socket_strerror(socket_last_error($sock)) ."\n"; } // 關閉連線成功的子socket socket_close($msgsock); } while(true); // 關閉等待接入的socket socket_close($sock); ?> 伺服器端的程式碼,需要在 cmd 下或者 CLI模式下執行,開啟命令列視窗,輸入如下命令: php E:\xampp\htdocs\demo\socket_server.php 就可以在伺服器端執行socket服務。 注意:伺服器端的命令列視窗不可關閉。 客戶端的程式碼:
(在 E:\xampp\htdocs\demo 下新建一個php檔案socket_client.php) <?php $address = '127.0.0.1'; $service_port = 10005; // 建立並返回一個套接字(通訊節點) $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if ($socket === false) { echo "socket_create() failed, reason: ".socket_strerror(socket_last_error())."\n"; }  echo "Attempting to connect to '$address' on port '$service_port'..."; // 發起socket連線請求 $result = socket_connect($socket, $address, $service_port); if($result === false) { echo "socket_connect() failed, reason: ".socket_strerror(socket_last_error($socket))."\n"; } else { echo "Connect success. \n"; } $input = "This is a message from client"."\n"; // 向socket伺服器傳送訊息 socket_write($socket, $input, strlen($input)); echo  "Client send success \n"; echo "Reading response:\n"; // 讀取socket伺服器傳送的訊息 while ($out = socket_read($socket, 8192)) { echo $out; } echo PHP_EOL; socket_close($socket); // 關閉socket連線 ?> php E:\xampp\htdocs\demo\socket_client.php 就可以看到客戶端與伺服器端進行通訊的結果。 最後,推薦使用Workerman 來實現 socket 通訊。(詳情可參考
Workerman官網
) Workerman 是一款純 PHP 開發開源高效能PHP Socket伺服器框架。被廣泛的用於手機app、手遊服務端、網路遊戲伺服器、聊天室伺服器、硬體通訊伺服器、智慧家居、車聯網、物聯網等領域的開發。 支援TCP長連線,支援Websocket、HTTP等協議,支援自定義協議。基於workerman,開發者可以更專注於業務邏輯開發,不必再為 PHP Socket 底層開發而煩惱。