這篇文章主要介紹了PHP SOCKET編程詳解,需要的朋友可以參考下
1. 預備知識
一直以來很少看到有多少人使用php的socket模塊來做一些事情,大概大家都把它定位在腳本語言的范疇內吧,但是其實php的socket模塊可以做很多事情,包括做ftplist,http post提交,smtp提交,組包并進行特殊報文的交互(如smpp協議),whois查詢。這些都是比較常見的查詢。
特別是php的socket擴展庫可以做的事情簡直不會比c差多少。
php的socket連接函數
1、集成于內核的socket
這個系列的函數僅僅只能做主動連接無法實現端口監聽相關的功能。而且在4.3.0之前所有socket連接只能工作在阻塞模式下。
此系列函數包括
fsockopen,pfsockopen
這兩個函數的具體信息可以查詢php.net的用戶手冊
他們均會返回一個資源編號對于這個資源可以使用幾乎所有對文件操作的函數對其進行操作如fgets(),fwrite(), fclose()等單注意的是所有函數遵循這些函數面對網絡信息流時的規律,例如:
fread() 從文件指針 handle 讀取最多 length 個字節。 該函數在讀取完 length 個字節數,或到達 EOF 的時候,或(對于網絡流)當一個包可用時就會停止讀取文件,視乎先碰到哪種情況。
可以看出對于網絡流就必須注意取到的是一個完整的包就停止。
2、php擴展模塊帶有的socket功能。
php4.x 以后有這么一個模塊extension=php_sockets.dll,Linux上是一個extension=php_sockets.so。
當打開這個此模塊以后就意味著php擁有了強大的socket功能,包括listen端口,阻塞及非阻塞模式的切換,multi-client 交互式處理等
這個系列的函數列表參看http://www.php.net/manual/en/ref.sockets.php
看過這個列表覺得是不是非常豐富呢?不過非常遺憾這個模塊還非常年輕還有很多地方不成熟,相關的參考文檔也非常少:(
我也正在研究中,因此暫時不具體討論它,僅給大家一個參考文章
http://www.zend.com/pecl/tutorials/sockets.php
2. 使用PHP socket擴展
服務器端代碼:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 <?php /** * File name server.php * 服務器端代碼 * * @author guisu.huang * @since 2012-04-11 * */ //確保在連接客戶端時不會超時 set_time_limit(0); //設置IP和端口號 $address = "127.0.0.1"; $port = 2046; //調試的時候,可以多換端口來測試程序! /** * 創建一個SOCKET * AF_INET=是ipv4 如果用ipv6,則參數為 AF_INET6 * SOCK_STREAM為socket的tcp類型,如果是UDP則使用SOCK_DGRAM */ $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("socket_create() 失敗的原因是:" . socket_strerror(socket_last_error()) . "/n"); //阻塞模式 socket_set_block($sock) or die("socket_set_block() 失敗的原因是:" . socket_strerror(socket_last_error()) . "/n"); //綁定到socket端口 $result = socket_bind($sock, $address, $port) or die("socket_bind() 失敗的原因是:" . socket_strerror(socket_last_error()) . "/n"); //開始監聽 $result = socket_listen($sock, 4) or die("socket_listen() 失敗的原因是:" . socket_strerror(socket_last_error()) . "/n"); echo "OKnBinding the socket on $address:$port ... "; echo "OKnNow ready to accept connections.nListening on the socket ... n"; do { // never stop the daemon //它接收連接請求并調用一個子連接Socket來處理客戶端和服務器間的信息 $msgsock = socket_accept($sock) or die("socket_accept() failed: reason: " . socket_strerror(socket_last_error()) . "/n"); //讀取客戶端數據 echo "Read client data n"; //socket_read函數會一直讀取客戶端數據,直到遇見n,t或者字符.PHP腳本把這寫字符看做是輸入的結束符. $buf = socket_read($msgsock, 8192); echo "Received msg: $buf n"; //數據傳送 向客戶端寫入返回結果 $msg = "welcome n"; socket_write($msgsock, $msg, strlen($msg)) or die("socket_write() failed: reason: " . socket_strerror(socket_last_error()) ."/n"); //一旦輸出被返回到客戶端,父/子socket都應通過socket_close($msgsock)函數來終止 socket_close($msgsock); } while (true); socket_close($sock);新聞熱點
疑難解答