一、Socket 簡介
1、socket只不過是一個數據結構。
2、使用這個socket數據結構去開始一個客戶端和服務器之間的會話。
3、服務器是一直在監聽准備產生一個新的會話。當一個客戶端連接服務器,它就打開服務器正在進行監聽的一個端口進行會話。
4、服務器端接受客戶端的連接請求,那么就進行一次循環。現在這個客戶端就能夠發送信息到服務器,服務器也能發送信息給客戶端。
二、Socket 變量
產生一個Socket,你需要三個變量:一個協議、一個socket類型和一個公共協議類型。
1、協議
AF_INET- //產生socket的協議,使用TCP或UDP來傳輸,用在IPv4的地址
- AF_INET6
- //產生socket的協議,使用TCP或UDP來傳輸,用在IPv6的地址
- AF_UNIX
- //本地協議,使用在Unix和Linux系統上,它很少使用,一般都是當客戶端和服務器在同一台機器上的時候使用
2、Socket類型
SOCK_STREAM
- //這個協議是按照順序的、可靠的、數據完整的基於字節流的連接。這是一個使用最多的socket類型,這個socket是使用TCP來進行傳輸。
- SOCK_DGRAM
- //這個協議是無連接的、固定長度的傳輸調用。該協議是不可靠的,使用UDP來進行它的連接。
- SOCK_SEQPACKET
- //這個協議是雙線路的、可靠的連接,發送固定長度的數據包進行傳輸。必須把這個包完整的接受才能進行讀取。
- SOCK_RAW
- //這個socket類型提供單一的網絡訪問,這個socket類型使用ICMP公共協議。(ping、traceroute使用該協議)
- SOCK_RDM
- //這個類型是很少使用的,在大部分的操作系統上沒有實現,它是提供給數據鏈路層使用,不保證數據包順序
3、公共協議
ICMP
- //互聯網控制消息協議,主要使用在網關和主機上,用來檢查網絡狀況和報告錯誤信息
- UDP
- //用戶數據報文協議,它是一個無連接,不可靠的傳輸協議
- TCP
- //傳輸控制協議,這是一個使用最多的可靠的公共協議,它能保證數據包能夠到達接受者那兒,如果在傳輸過程中發生錯誤,那么它將重新發送出錯數據包。
三、Socket函數
1、socket_create
作用:產生一個socket,相當於產生一個socket的數據結構
用法:socket_create ( int domain, int type, int protocol )
參數:domain,協議;type,類型;protocol,公共協議
返回:socket resource on success, or FALSE on error
2、socket_bind
作用:把socket綁定在一個IP地址和端口上
用法:socket_bind ( resource socket, string address [, int port] )
參數:socket,socket resource;address,ip地址;port,端口
返回:Boolean
3、socket_accept
作用:接受一個Socket連接
用法:socket_accept ( resource socket )
參數:socket,socket resource
返回:Returns a new socket resource on success, or FALSE on error.
4、socket_connect()
作用:開始一個socket連接
用法:socket_connect ( resource socket, string address [, int port] )
參數:socket,socket resource;address,ip地址;port,端口
返回:Boolean
5、socket_listen
作用:監聽由指定socket的所有連接
用法:socket_listen ( resource socket [, int backlog] )
參數:socket,socket resource;
返回:Boolean
6、socket_read
作用:讀取指定長度的數據
用法:socket_read ( resource socket, int length [, int type] )
參數:socket,socket resource;length,字符長度;type,PHP_BINARY_READ |PHP_NORMAL_READ
返回:string
7、socket_write
作用:寫數據到socket緩存
用法:socket_write ( resource socket, string buffer [, int length] )
參數:socket,socket resource;buffer,字符;length,字符長度;
返回:Boolean
8、socket_send()
作用:這個函數發送數據到已連接的socket
用法:socket_send ( resource socket, string buf, int len, int flags )
參數:socket,socket resource;buf,字符;len,字符長度;
返回:Boolean
9、socket_last_error
作用:獲取當前socket的最后錯誤代碼
用法:socket_last_error ( [resource socket] )
參數:socket,socket resource;
返回:int
10、socket_strerror
作用:返回指定錯誤號的詳細錯誤
用法:socket_strerror ( int errno )
參數:errno,socket_last_error no;
返回:string
11、socket_close
作用:關閉一個socket資源
用法:socket_close ( [resource socket] )
參數:socket,socket resource;
返回:null
四、使用說明
確認打開socket方法
a、編輯PHP.ini文件,去掉 extension=php_sockets.dll 前面的注釋:
b、代碼來加載擴展庫
if(!extension_loaded('sockets')) {
- if(strtoupper(substr(PHP_OS, 0, 3)) == "WIN") {
- dl('php_sockets.dll');
- }else{
- dl('sockets.so');
- }
- }
五、socket編程
1、服務器端
功能:
a、初始化一個socket並且打開一個緩存收發數據。
b、等待連接,一旦產生一個連接,它將打印“Socket connected”在服務器端的屏幕上。
c、服務器檢查緩沖區,如果緩沖區里有數據,它將把數據發送到連接過來的計算機。
然后它發送這個數據的接受信息,一旦它接受了信息,就把信息保存到數據里,並且讓連接的計算機知道這些信息,最后關閉連接。
d、連接關閉后,服務器又開始處理下一次連接。
// 獲取協議
- $commonProtocol = getprotobyname("tcp");
- //產生一個socket
- $socket = socket_create(AF_INET, SOCK_STREAM, $commonProtocol);
- //把socket綁定在一個IP地址和端口上
- socket_bind($socket, 'localhost', 1337);
- //監聽由指定socket的所有連接
- socket_listen($socket);
- //初始化buffer
- $buffer = "NO DATA";
- while(true) {
- //接受一個Socket連接
- $connection = socket_accept($socket);
- printf("Socket connected\r\n");
- // 檢測 buffer
- if($buffer != ""){
- printf("Something is in the buffer...sending data...\r\n");
- //寫數據到socket緩存
- socket_write($connection, $buffer . "\r\n");
- printf("Wrote to socket\r\n");
- }else {
- printf("No Data in the buffer\r\n");
- }
- //讀取指定長度的數據
- while($data = socket_read($connection, 1024, PHP_NORMAL_READ))
- {
- $buffer = $data;
- //寫數據到socket緩存
- socket_write($connection, "Information Received\r\n");
- printf("Buffer: " . $buffer . "\r\n");
- }
- //關閉一個socket資源
- socket_close($connection);
- printf("Closed the socket\r\n\r\n");
- }
2、客戶端
功能:
a、客戶端連接到服務器。客戶端讀取數據。
b、如果這是第一時間到達這個循環的首次連接,這個服務器將發送“NO DATA”返回給客戶端。如果情況發生了,這個客戶端在連接之上。
c、客戶端發送它的數據到服務器,數據發送給服務器,客戶端等待響應。一旦接受到響應,那么它將把響應寫到屏幕上。
// 創建 socket
- $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
- //鏈接 socket
- $connection = socket_connect($socket,'localhost', 1337);
- //讀取指定長度的數據
- while($buffer = socket_read($socket, 1024, PHP_NORMAL_READ)) {
- if($buffer == "NO DATA") {
- printf("NO DATA");
- break;
- }else{
- // 輸出 buffer
- printf("Buffer Data: " . $buffer . "");
- }
- }
- printf("Writing to Socket");
- //寫數據到socket緩存
- if(!socket_write($socket, "SOME DATA\r\n")){
- printf("Write failed");
- }
- //讀取指定長度的數據
- while($buffer = socket_read($socket, 1024, PHP_NORMAL_READ)){
- printf("Data sent was: SOME DATA Response was:" . $buffer . "");
- }
- printf("Done Reading from Socket");