PHP-Socket服務端客戶端傳送接收通訊例項詳解
Socket介紹
什麼是socket 所謂socket通常也稱作"套接字",用於描述IP地址和埠,是一個通訊鏈的控制代碼。應用程式通常通過"套接字"向網路發出請求或者應答網路請求。
在Internet上的主機一般運行了多個服務軟體,同時提供幾種服務。每種服務都開啟一個Socket,並繫結到一個埠上,不同的埠對應於不同的服務。
Socket連線過程
根據連線啟動的方式以及本地套接字要連線的目標,套接字之間的連線過程可以分為三個步驟:伺服器監聽,客戶端請求,連線確認。
(1)伺服器監聽:是伺服器端套接字並不定位具體的客戶端套接字,而是處於等待連線的狀態,實時監控網路狀態。
(2)客戶端請求:是指由客戶端的套接字提出連線請求,要連線的目標是伺服器端的套接字。為此,客戶端的套接字必須首先描述它要連線的伺服器的套接字,指出伺服器端套接字的地址和埠號,然後就向伺服器端套接字提出連線請求。
(3)連線確認:是指當伺服器端套接字監聽到或者說接收到客戶端套接字的連線請求,它就響應客戶端套接字的請求,建立一個新的執行緒,把伺服器端套接字的描述發給客戶端,一旦客戶端確認了此描述,連線就建立好了。而伺服器端套接字繼續處於監聽狀態,繼續接收其他客戶端套接字的連線請求
1、測試環境:
伺服器ip:192.168.150.1
客戶端ip:192.168.150.2
2、測試過程:
客戶端伺服器將在本機(192.168.150.2)通過socket傳送資料到服務端(192.168.150.2)的socket伺服器上,服務端接收到客戶端傳送的資料後返回一些資訊給客戶端。
3、服務端檔案內容:
#server.php <?php //獲取tcp協議號碼。 $tcp = getprotobyname("tcp"); // 建立server端socket ,建立並返回一個套接字,也稱作一個通訊節點。一個典型的網路連線由 2 個套接字構成,一個執行在客戶端,另一個執行在伺服器端。 $socket = socket_create(AF_INET, SOCK_STREAM, $tcp); //繫結要監聽的ip和埠,這裡繫結的ip一定要寫區域網ip,寫成127.0.0.1客戶端將無法與服務端建議連線。 socket_bind($socket, '192.168.150.1', 10008); //監聽埠 socket_listen($socket); //初始化一個數據,和客戶端通訊 $buffer = "connect"; while (true) { // 接受客戶端請求過來的一個socket連線 $connection = socket_accept($socket); if(!$connection){ echo "connect faild"; }else{ echo "Socket connected\n"; // 向客戶端傳遞一個資訊資料 if ($buffer != "") { echo "send data to client\n"; socket_write($connection, $buffer . "\n"); echo "Wrote to socket\n"; } else { echo "no data in the buffer\n" ; } // 從客戶端獲取得的資料 while ($data = @socket_read($connection, 1024, PHP_NORMAL_READ)) { printf("Buffer: " . $data . "\n"); //取得資訊給客戶端一個反饋, Thank you client, you data is Received success發給客戶端的迴應資訊。 socket_write($connection, "Thank you client, you data is Received success\n"); } } //關閉 socket socket_close($connection); printf("Closed the socket\n"); } ?>
4、客戶端檔案內容: client.php <?php // 建立客戶端的socet連線 $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); //連線伺服器端socket $connection = socket_connect($socket, '192.168.150.1', 10008); //要傳送到服務端的資訊。 $send_data = "This data will Send to server!"; //客戶端去連線服務端並接受服務端返回的資料,如果返回的資料保護not connect就提示不能連線。 while ($buffer = @socket_read($socket, 1024, PHP_NORMAL_READ)) { if (preg_match("/not connect/",$buffer)) { echo "don`t connect\n"; break; } else { //服務端傳來的資訊 echo "Buffer Data: " . $buffer . "\n"; echo "Writing to Socket\n"; // 將客戶的資訊寫到通道中,傳給伺服器端 if (!socket_write($socket, "$send_data\n")) { echo "Write failed\n"; } //伺服器端收到資訊後,客戶端接收服務端傳給客戶端的迴應資訊。 while ($buffer = socket_read($socket, 1024, PHP_NORMAL_READ)) { echo "sent to server:$send_data\n response from server was:" . $buffer . "\n"; } } } ?>
5、在服務端socket服務啟動程序。
#/usr/local/php/bin/php -a /home/server.php
Interactive mode enabled
6、服務端啟動後檢視啟動的程序及埠。
#netstat -tnlp |grep 10008
tcp 0 0 192.168.150.13:10008 0.0.0.0:* LISTEN 28892/php
7、在客戶端(192.168.1.2)上執行傳輸
#/usr/local/php/bin/php -a client.php
Interactive mode enabled
Buffer Data: connect
Writing to Socket
sent to server:This data will Send to server!
response from server was:Thank you client, you data Information Received
8、回到服務端上檢視接收到的資訊。
#/usr/local/php/bin/php -a /home/server.php
Interactive mode enabled
Socket connected
send data to client
Wrote to socket
Buffer: This data will Send to server!
9、參考資料
socket_create()函式需要三個引數:一個協議、一個socket型別、一個公共協議。socket_create()函式執行成功返回一個包含socket的資源型別,如果沒有成功則返回false。
Socket函式
函式名 描述
socket_accept() 接受一個Socket連線
socket_bind() 把socket繫結在一個IP地址和埠上
socket_close() 關閉一個socket資源
socket_connect() 開始一個socket連線
socket_create() 產生一個socket,相當於產生一個socket的資料結構
socket_listen() 監聽由指定socket的所有連線
socket_read() 讀取指定長度的資料
socket_readv() 讀取從分散/聚合陣列過來的資料
socket_send() 這個函式傳送資料到已連線的socket
socket_write() 寫資料到socket快取
socket_writev() 寫資料到分散/聚合陣列
參考文件:http://blog.51yip.com/php/673.html