首頁 >後端開發 >php教程 >PHP中的socket函數

PHP中的socket函數

不言
不言原創
2018-05-04 15:16:111811瀏覽

這篇文章主要介紹了關於PHP中的socket函數,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

要創建基於socket的應用程序,就需要詳細了解socket的操作方法,這裡列舉PHP中一些重要的socket函數。

1. socket_create# ( int $domain# , int $type , #int $protocol )

此函數用來建立一個socket,它有三個參數,傳回值是一個句柄(資源)。

$domain 指定建立socket時使用的通訊協定族,其可選的值為:

  • AF_INET: 基於IPv4的Internet協定

  • #AF_INET6:#基於IPv6的Internet協定

  • AF_UNIX:UNIX本地通訊協定

#$type 指定socket通訊的互動類型,其可選的值為:

  • SOCK_STREAM:提供序列化的、可靠的、全雙工的、基於連接的位元組流傳輸,支援TCP

  • SOCK_DGRAM:提供資料封包的、無連線的、固定最大長度的、自動定址功能的傳輸,支援UDP

  • SOCK_SEQPACKET:提供序列化的、可靠的、雙通道的、基於連接的資料封包傳輸

  • SOCK_RAW:提供原始的網路存取協議,可手動建構特殊協議類型的套接字,支援ICMP請求(如ping)

  • SOCK_RDM:提供可靠的資料封包傳輸,無法保證順序

$protocol 指定socket使用哪種具體的傳輸協議,包括ICMP、UDP、TCP,常數SOL_UDP對應UDP,常數SOL_TCP對應常數TCP。

2. socket_bind # ( resource $socket# , string $address [, int $port = 0 ] )

此函數用於將IP位址和連接埠綁定到socket_create所建立的句柄中,有三個參數,傳回布林值。

$socket 是必選參數,代表socket_create函數所建立的句柄

$address 是必選參數,代表要綁定的IP位址

$port 是可選參數,代表要綁定的連接埠號,指定哪個連接埠用來監聽socket連接,當socket_create函數的第一當一個參數為AF_INET時,需要指定這個參數。

#3. #socket_listen ( resource $socket# [, int $backlog = 0 ] )

此函數用於監聽即將接入的socket連接,僅當socket的交互類型為SOCK_STREAM或SOCK_SEQPACKET時可

用,它有兩個參數,返回布林值。

$socket  是必選參數,代表socket_create函數建立的句柄(且已綁定了主機)

$backlog 是可選參數,表示佇列中等待處理的(允許積壓的)最大連接數。

4. socket_set_block ( resource #$socket# )

此函數用於將socket句柄設定為阻塞模式,只有一個必選參數,傳回布林值。它可以將非阻塞模式的socket轉換為阻塞模式。

當在一個阻塞模式的socket中執行某種操作(receive、send、connect、accept等)時,腳本將暫停執行,直到它收到一個訊號或它完成了該操作。

$socket 是必選參數,代表一個有效的socket句柄(被socket_create或socket_accept所建立的)。

簡單介紹一下阻塞模式和非阻塞模式的差異:

非阻塞是指函數操作在無法立刻得到結果之前,不會阻塞目前的線程,而會立即返回。而阻塞是指乾不完就不准回來,必須得到對方的回應後才能繼續下一步。特別是當使用者比較多時,設定成非阻塞是必要的。如果是阻塞模式,若兩個客戶端同時連線上,伺服器端在處理一個客戶端請求時,另外一個客戶端的請求就會被阻塞,只有等到前一個客戶端的事情處理完了之後,後一個客戶端的請求才會被響應。

#5. socket_write ( resource $socket , string $buffer [, int $length = 0 ] )

此函數用於在socket中寫入指定大小的緩衝數據,有三個參數,傳回寫入的資料的位元組數。

$socket 是必選參數,代表一個有效的socket句柄。

$buffer 是必選參數,指定要寫入的字串資料。

$length 是可選參數,指定輪流寫入socket中的資料的位元組數,如果它的值大於$buffer的位元組數,它會靜默地截取至$buffer的位元組數長度。

#6. #socket_read ( resource $socket ,  #int $length [, #int $type = PHP_BINARY_READ# ] )

此函數用於從socket讀取指定位元組長度的數據,有三個參數,傳回讀取的字串資料。

$socket 是必選參數,代表一個有效的socket句柄。
$length 是必選參數,指定讀取的位元組長度。

$type 是可選參數,預設值為PHP_BINARY_READ,即安全讀取二進位資料;另一個可選的值為#PHP_NORMAL_READ,表示當遇到\r 或\n 時,停止讀取。

7. pfsockopen ( string $hostname [, int $port = -1 [, int &$errno [, string &$errstr [, float $timeout = ini_get("default_socket_timeout") ]]]] )

此函數用於實現一個持久的socket連接,即長連接,傳回一個句柄。它與 fsockopen 的差別在於,pfsockopen 建立的連接,在腳本執行完畢後,不會斷開。

8. socket_set_option
 ( 
resource$socket

# , 

int$level , #int$optname
 , 
mixed$optval
# )

此函數用來設定socket的控制選項,有四個參數,傳回布林值。
$socket 是必選參數,代表一個有效的socket句柄。

#$level 是必選參數,指定option起作用的協定級別,一般取常數SOL_SOCKET。

#$optname 是必選參數,指定要控制的選項名稱。

##################$optval是必選參數,指定選項的值。 #####################################9. socket_last_error###### ([ ### ###resource######$socket###### ] )#######

該函數用於取得任何socket函數產生的最後錯誤代號,傳回值為整數。

10. #socket_strerror ( #int $errno

 )

此函數用於取得錯誤代號代表的錯誤描述,並傳回值為字串。

身為非底層程式設計師,要深入了解socket的內部實作機制是很困難的,我們只需明白socket是一套作業系統封裝好的實現進程通訊的函數,會建立和調用就夠了。

PHP的語言特性和自身定位決定了它只適合做socket客戶端,而不適合做socket伺服器端。

因為socket主要針對底層和網路服務開發,一般伺服器端都是用C 或Java 等語言實現,這樣能更好地操作底層,對網路服務開發中遇到的問題(如並發、阻塞等)也有成熟完善的解決方案,而PHP顯然不適合這種應用場景。

實際上,PHP操作MySQL資料庫也是透過socket進行的,這正是由於socket屏蔽了底層的協議,使得網路服務之間的互聯互通變得簡單。

除了傳統的伺服器端語言實現的socket外,隨著HTML5的流行,瀏覽器用戶端實現的WebSocket也逐漸興起,對於這一點值得關注,FlashSocket也是一個不錯的解決方案。 要在客戶端操作socket,可使用fsockopen、socket_create 或stream_socket_client 等函式實現,如果是PHP5,推薦使用stream_socket_client。

socket互動應用實例:使用socket提交表單

新建一個test.php 文件,向 

http:// demo.com/index.php?id=1  提交表單數據,程式碼如下

[php] view plain copy
<?php  
$data = array(&#39;comment&#39;=>&#39;this is a robot comment&#39;);  
$data = http_build_query($data);  
$out = "POST http://demo.com/index.php?id=1 HTTP/1.1\r\n";  // 通过POST方式发送数据  
$out .= "Host: demo.com\r\n";  
$out .= "Content-type: application/x-www-form-urlencoded; charset=UTF-8\r\n";  
$out .= "Content-length: ".strlen($data)."\r\n";  
$out .= "User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:48.0) Gecko/20100101 Firefox/48.0"."\r\n";  
$out .= "Connection: close"."\r\n"."\r\n";    // 注意:此处有两个 \r\n
$out .= $data."\r\n";   // 正文数据
$fp = fsockopen("demo.com", 80, $errno, $errstr, 30);  // 创建socket客户端连接
// $fp = stream_socket_client("tcp://demo.com:80", $errno, $errstr, 30);  推荐这种写法
fwrite($fp, $out);    // 向服务器发送数据
while (!feof($fp)) {  
    echo fgets($fp, 1280);    // 读取服务器响应的数据
}  
fclose($fp);  // 关闭socket连接
?>

########################################################## ########需要注意以下幾點:#########################
  • fsockopen的第一个参数,也可以使用IP地址,不要带 http:// 字符串,除非使用SSL等

  • 请求头(headers)不一定要带上所有的头域,一般只需带上几个核心的header即可

  • 在最后一个header处,即 Connection 后有两个换行

  • 注意编码问题

如果是PHP5,建议使用 stream_socket_client 代替 fsockopen,也就是将下面的代码:

$fp = fsockopen("demo.com", 80, $errno, $errstr, 30);

改为:

$fp = stream_socket_client("tcp://demo.com:80", $errno, $errstr, 30);

在PHP中,99.9%的socket应用属于流套接字的范畴,由于数据包套接字和原始套接字涉及比较底层的协议知识,这里就不作深究,有兴趣的朋友可自行学习。

相关推荐:

PHP中PDO事务处理操作示例


以上是PHP中的socket函數的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn