Socket介紹
php
什麼是socket 所謂socket一般也稱做"套接字",用於描述IP地址和端口,是一個通訊鏈的句柄。應用程序一般經過"套接字"向網絡發出請求或者應答網絡請求。html
在Internet上的主機通常運行了多個服務軟件,同時提供幾種服務。每種服務都打開一個Socket,並綁定到一個端口上,不一樣的端口對應於不一樣的服務。數組
Socket鏈接過程緩存
根據鏈接啓動的方式以及本地套接字要鏈接的目標,套接字之間的鏈接過程能夠分爲三個步驟:服務器監聽,客戶端請求,鏈接確認。服務器
(1)服務器監聽:是服務器端套接字並不定位具體的客戶端套接字,而是處於等待鏈接的狀態,實時監控網絡狀態。網絡
(2)客戶端請求:是指由客戶端的套接字提出鏈接請求,要鏈接的目標是服務器端的套接字。爲此,客戶端的套接字必須首先描述它要鏈接的服務器的套接字,指出服務器端套接字的地址和端口號,而後就向服務器端套接字提出鏈接請求。數據結構
(3)鏈接確認:是指當服務器端套接字監聽到或者說接收到客戶端套接字的鏈接請求,它就響應客戶端套接字的請求,創建一個新的線程,把服務器端套接字的描述發給客戶端,一旦客戶端確認了此描述,鏈接就創建好了。而服務器端套接字繼續處於監聽狀態,繼續接收其餘客戶端套接字的鏈接請求socket
socket百科:http://baike.baidu.com/view/13870.htm tcp
一、測試環境:ide
服務器ip:192.168.150.1
客戶端ip:192.168.150.2
二、測試過程:
客戶端服務器將在本機(192.168.150.2)經過socket發送數據到服務端(192.168.150.2)的socket服務器上,服務端接收到客戶端發送的數據後返回一些信息給客戶端。
三、服務端文件內容:
#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"); } ?>
四、客戶端文件內容: 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"; } } } ?>
五、在服務端socket服務啓動進程。
#/usr/local/php/bin/php -a /home/server.php
Interactive mode enabled
六、服務端啓動後查看啓動的進程及端口。
#netstat -tnlp |grep 10008
tcp 0 0 192.168.150.13:10008 0.0.0.0:* LISTEN 28892/php
七、在客戶端(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
八、回到服務端上查看接收到的信息。
#/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!
九、參考資料
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