通信需要服務(wù)端和客戶端組成:
服務(wù)端:使用php初始化socket然后綁定一個端口,對端口進(jìn)行監(jiān)聽。調(diào)用accept阻塞,等待客戶端連接。
客戶端:客戶端初始化一個socket,然后連接服務(wù)器,如果連接成功,這時客戶端與服務(wù)器端的連接就建立了。客戶端發(fā)送數(shù)據(jù)請求,服務(wù)器端接收請求并處理請求,然后把回應(yīng)數(shù)據(jù)發(fā)送給客戶端,客戶端讀取數(shù)據(jù),最后關(guān)閉連接,一次交互結(jié)束。
客戶端—服務(wù)端是可以彼此交互的應(yīng)用程序。客戶端和服務(wù)端之間的交互需要連接。Socket編程負(fù)責(zé)的就是為應(yīng)用程序之間建立可進(jìn)行交互的連接。
Socket連接過程
根據(jù)連接啟動的方式以及本地套接字要連接的目標(biāo),套接字之間的連接過程可以分為三個步驟:服務(wù)器監(jiān)聽,客戶端請求,連接確認(rèn)。
(1)服務(wù)器監(jiān)聽:是服務(wù)器端套接字并不定位具體的客戶端套接字,而是處于等待連接的狀態(tài),實時監(jiān)控網(wǎng)絡(luò)狀態(tài)。
(2)客戶端請求:是指由客戶端的套接字提出連接請求,要連接的目標(biāo)是服務(wù)器端的套接字。為此,客戶端的套接字必須首先描述它要連接的服務(wù)器的套接字,指出服務(wù)器端套接字的地址和端口號,然后就向服務(wù)器端套接字提出連接請求。
(3)連接確認(rèn):是指當(dāng)服務(wù)器端套接字監(jiān)聽到或者說接收到客戶端套接字的連接請求,它就響應(yīng)客戶端套接字的請求,建立一個新的線程,把服務(wù)器端套接字的描述發(fā)給客戶端,一旦客戶端確認(rèn)了此描述,連接就建立好了。而服務(wù)器端套接字繼續(xù)處于監(jiān)聽狀態(tài),繼續(xù)接收其他客戶端套接字的連接請求。
socket原理可以參考下面的流程圖:
下面通過一個服務(wù)端--客戶端的代碼實例來簡單實現(xiàn)一下socket通信整個過程
1. 其服務(wù)端代碼:
<?phpset_time_limit(0); //限制執(zhí)行時間 0為不限制$ip = '127.0.0.1';$port = 8001;//端口/**socket通信整個過程 socket_create //創(chuàng)建一個套接字socket_bind //給套接字綁定 ip 和端口socket_listen //監(jiān)聽套接字上的連接socket_accept //接受一個socket連接socket_read //接收客戶端 發(fā)送的數(shù)據(jù)socket_write //將數(shù)據(jù)寫到 socket 緩存 向客戶端發(fā)送socket_close //關(guān)閉套接字資源*/ if(($sock = socket_create(AF_INET,SOCK_STREAM,SOL_TCP)) < 0) { echo "socket_create() 失敗的原因是:".socket_strerror($sock)."/n";}if(($ret = socket_bind($sock,$ip,$port)) < 0) { echo "socket_bind() 失敗的原因是:".socket_strerror($ret)."/n";}if(($ret = socket_listen($sock,4)) < 0) { echo "socket_listen() 失敗的原因是:".socket_strerror($ret)."/n";}$count = 0;do { if (($msgsock = socket_accept($sock)) < 0) { echo "socket_accept() failed: reason: " . socket_strerror($msgsock) . "/n"; break; } else { //發(fā)到客戶端 $msg ="測試成功!/n"; socket_write($msgsock, $msg, strlen($msg)); echo "測試成功了啊/n"; $buf = socket_read($msgsock,8192); $talkback = "收到的信息:$buf/n"; echo $talkback; if(++$count >= 5){ break; }; } //echo $buf; socket_close($msgsock);} while (true);socket_close($sock);?>
運行php 文件,運行后 ,應(yīng)該看不見結(jié)果 , 可以使用 netstat -ntlp 查看 8001 端口是否被占用。參見下圖。
2. 其客戶端代碼:
<?phperror_reporting(E_ALL);set_time_limit(0);echo "socket通信客戶端/n";$port = 8001;//端口$ip = "127.0.0.1";//ip/**socket連接整個過程 socket_create //建立一個socket 連接 socket_connect // 開始一個socket連接 連接服務(wù)端 socket_write //將數(shù)據(jù)寫入緩存 向服務(wù)端發(fā)送 socket_read// 讀取服務(wù)端的結(jié)果 socket_close // 關(guān)閉套接字資源 */$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);if ($socket < 0) { echo "socket_create() failed: reason: " . socket_strerror($socket) . "/n";}else { echo "OK./n";}echo "試圖連接 '$ip' 端口 '$port'.../n";$result = socket_connect($socket, $ip, $port);if ($result < 0) { echo "socket_connect() failed./nReason: ($result) " . socket_strerror($result) . "/n";}else { echo "連接OK/n";}$in = "Ho/r/nfirst blood/r/n";$out = '';if(!socket_write($socket, $in, strlen($in))) { echo "socket_write() failed: reason: " . socket_strerror($socket) . "/n";}else { echo "發(fā)送到服務(wù)器信息成功!/n"; echo "發(fā)送的內(nèi)容為:<font color='red'>$in</font> <br>";}while($out = socket_read($socket, 8192)) { echo "接收服務(wù)器回傳信息成功!/n"; echo "接受的內(nèi)容為:",$out;}echo "關(guān)閉SOCKET.../n";socket_close($socket);echo "關(guān)閉OK/n";?>
在看看服務(wù)端的窗口結(jié)果:
說明: PHP 語言的特性決定了php 在這方面它只適合做客戶端,不適合做服務(wù)端。
【相關(guān)教程推薦】
1. 《VeVb.com獨孤九賤(4)-php視頻教程》
2. php編程從入門到精通全套教程
以上就是如何實現(xiàn)簡單的php socket通信的詳細(xì)內(nèi)容,更多請關(guān)注 其它相關(guān)文章!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。
新聞熱點
疑難解答
圖片精選