這篇文章主要介紹了關於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('comment'=>'this is a robot comment');
$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中的socket函數的詳細內容。更多資訊請關注PHP中文網其他相關文章!