PHP-Socket服務端客戶端發送接收通信實例詳解

Socket介紹

什麼是socket 所謂socket通常也稱作"套接字",用於描述IP地址和端口,是一個通信鏈的句柄。應用程序通常通過"套接字"向網絡發出請求或者應答網絡請求。

在Internet上的主機一般運行了多個服務軟件,同時提供幾種服務。每種服務都打開一個Socket,並綁定到一個端口上,不同的端口對應於不同的服務。

Socket連接過程

根據連接啓動的方式以及本地套接字要連接的目標,套接字之間的連接過程可以分爲三個步驟:服務器監聽,客戶端請求,連接確認。

(1)服務器監聽:是服務器端套接字並不定位具體的客戶端套接字,而是處於等待連接的狀態,實時監控網絡狀態。

(2)客戶端請求:是指由客戶端的套接字提出連接請求,要連接的目標是服務器端的套接字。爲此,客戶端的套接字必須首先描述它要連接的服務器的套接字,指出服務器端套接字的地址和端口號,然後就向服務器端套接字提出連接請求。

(3)連接確認:是指當服務器端套接字監聽到或者說接收到客戶端套接字的連接請求,它就響應客戶端套接字的請求,建立一個新的線程,把服務器端套接字的描述發給客戶端,一旦客戶端確認了此描述,連接就建立好了。而服務器端套接字繼續處於監聽狀態,繼續接收其他客戶端套接字的連接請求

socket百科:http://baike.baidu.com/view/13870.htm


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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章