PHP-Socket服务端客户端发送接收通信实例详解
Socket介紹
什么是socket 所謂socket通常也稱(chēng)作"套接字",用于描述IP地址和端口,是一個(gè)通信鏈的句柄。應(yīng)用程序通常通過(guò)"套接字"向網(wǎng)絡(luò)發(fā)出請(qǐng)求或者應(yīng)答網(wǎng)絡(luò)請(qǐng)求。
在Internet上的主機(jī)一般運(yùn)行了多個(gè)服務(wù)軟件,同時(shí)提供幾種服務(wù)。每種服務(wù)都打開(kāi)一個(gè)Socket,并綁定到一個(gè)端口上,不同的端口對(duì)應(yīng)于不同的服務(wù)。
Socket連接過(guò)程
根據(jù)連接啟動(dòng)的方式以及本地套接字要連接的目標(biāo),套接字之間的連接過(guò)程可以分為三個(gè)步驟:服務(wù)器監(jiān)聽(tīng),客戶(hù)端請(qǐng)求,連接確認(rèn)。
(1)服務(wù)器監(jiān)聽(tīng):是服務(wù)器端套接字并不定位具體的客戶(hù)端套接字,而是處于等待連接的狀態(tài),實(shí)時(shí)監(jiān)控網(wǎng)絡(luò)狀態(tài)。
(2)客戶(hù)端請(qǐng)求:是指由客戶(hù)端的套接字提出連接請(qǐng)求,要連接的目標(biāo)是服務(wù)器端的套接字。為此,客戶(hù)端的套接字必須首先描述它要連接的服務(wù)器的套接字,指出服務(wù)器端套接字的地址和端口號(hào),然后就向服務(wù)器端套接字提出連接請(qǐng)求。
(3)連接確認(rèn):是指當(dāng)服務(wù)器端套接字監(jiān)聽(tīng)到或者說(shuō)接收到客戶(hù)端套接字的連接請(qǐng)求,它就響應(yīng)客戶(hù)端套接字的請(qǐng)求,建立一個(gè)新的線(xiàn)程,把服務(wù)器端套接字的描述發(fā)給客戶(hù)端,一旦客戶(hù)端確認(rèn)了此描述,連接就建立好了。而服務(wù)器端套接字繼續(xù)處于監(jiān)聽(tīng)狀態(tài),繼續(xù)接收其他客戶(hù)端套接字的連接請(qǐng)求
socket百科:http://baike.baidu.com/view/13870.htm
?
1、測(cè)試環(huán)境:
服務(wù)器ip:192.168.150.1
客戶(hù)端ip:192.168.150.2
2、測(cè)試過(guò)程:
客戶(hù)端服務(wù)器將在本機(jī)(192.168.150.2)通過(guò)socket發(fā)送數(shù)據(jù)到服務(wù)端(192.168.150.2)的socket服務(wù)器上,服務(wù)端接收到客戶(hù)端發(fā)送的數(shù)據(jù)后返回一些信息給客戶(hù)端。
3、服務(wù)端文件內(nèi)容:
| 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 | #server.php <?php? //獲取tcp協(xié)議號(hào)碼。 $tcp?=?getprotobyname("tcp");?? //?建立server端socket?,創(chuàng)建并返回一個(gè)套接字,也稱(chēng)作一個(gè)通訊節(jié)點(diǎn)。一個(gè)典型的網(wǎng)絡(luò)連接由?2?個(gè)套接字構(gòu)成,一個(gè)運(yùn)行在客戶(hù)端,另一個(gè)運(yùn)行在服務(wù)器端。 $socket?=?socket_create(AF_INET,?SOCK_STREAM,?$tcp);? //綁定要監(jiān)聽(tīng)的ip和端口,這里綁定的ip一定要寫(xiě)局域網(wǎng)ip,寫(xiě)成127.0.0.1客戶(hù)端將無(wú)法與服務(wù)端建議連接。 socket_bind($socket,?'192.168.150.1',?10008);???? ?//監(jiān)聽(tīng)端口???? socket_listen($socket);????? ?? //初始化一個(gè)數(shù)據(jù),和客戶(hù)端通信? $buffer?=?"connect";? while?(true)?{? ????//?接受客戶(hù)端請(qǐng)求過(guò)來(lái)的一個(gè)socket連接? ????$connection?=?socket_accept($socket);? ????if(!$connection){? ????????echo?"connect?faild";? ????}else{? ????????????echo?"Socket?connected\n";? ????????????//?向客戶(hù)端傳遞一個(gè)信息數(shù)據(jù)? ????????????if?($buffer?!=?"")?{? ????????????????echo?"send?data?to?client\n";? ????????????????socket_write($connection,?$buffer?.?"\n");? ????????????????echo?"Wrote?to?socket\n";? ????????????}?else?{? ????????????????echo?"no?data?in?the?buffer\n"?;? ????????????}? ????????????//?從客戶(hù)端獲取得的數(shù)據(jù) ????????????while?($data?=?@socket_read($connection,?1024,?PHP_NORMAL_READ))?{? ????????????????????printf("Buffer:?"?.?$data?.?"\n");? ???????????????//取得信息給客戶(hù)端一個(gè)反饋,?Thank?you?client,?you?data?is??Received?success發(fā)給客戶(hù)端的回應(yīng)信息。 ????????????????????socket_write($connection,?"Thank?you?client,?you?data?is??Received?success\n");? ????????????}? ????}? ????//關(guān)閉?socket ????socket_close($connection);? ????printf("Closed?the?socket\n");? }? ?> |
?
| 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 | 4、客戶(hù)端文件內(nèi)容: client.php <?php? //?建立客戶(hù)端的socet連接? $socket?=?socket_create(AF_INET,?SOCK_STREAM,?SOL_TCP);? ??//連接服務(wù)器端socket? $connection?=?socket_connect($socket,?'192.168.150.1',?10008);?? //要發(fā)送到服務(wù)端的信息。 $send_data?=?"This?data?will?Send?to?server!"; //客戶(hù)端去連接服務(wù)端并接受服務(wù)端返回的數(shù)據(jù),如果返回的數(shù)據(jù)保護(hù)not?connect就提示不能連接。 while?($buffer?=?@socket_read($socket,?1024,?PHP_NORMAL_READ))?{? ????if?(preg_match("/not?connect/",$buffer))?{? ????????echo?"don`t?connect\n";? ????????break;? ????}?else?{? ????????//服務(wù)端傳來(lái)的信息? ????????echo?"Buffer?Data:?"?.?$buffer?.?"\n";? ????????echo?"Writing?to?Socket\n";? ????????//?將客戶(hù)的信息寫(xiě)到通道中,傳給服務(wù)器端? ????????if?(!socket_write($socket,?"$send_data\n"))?{? ????????????echo?"Write?failed\n";? ????????}? ????????//服務(wù)器端收到信息后,客戶(hù)端接收服務(wù)端傳給客戶(hù)端的回應(yīng)信息。? ????????while?($buffer?=?socket_read($socket,?1024,?PHP_NORMAL_READ))?{? ????????????????echo?"sent?to?server:$send_data\n?response?from?server?was:"?.?$buffer?.?"\n";? ????????}???????? ?? ????}? }? ?? ?> |
?
5、在服務(wù)端socket服務(wù)啟動(dòng)進(jìn)程。
#/usr/local/php/bin/php -a /home/server.php
Interactive mode enabled
6、服務(wù)端啟動(dòng)后查看啟動(dòng)的進(jìn)程及端口。
#netstat -tnlp |grep 10008
tcp??????? 0????? 0 192.168.150.13:10008??????? 0.0.0.0:*?????????????????? LISTEN????? 28892/php?
?
7、在客戶(hù)端(192.168.1.2)上執(zhí)行傳輸
#/usr/local/php/bin/php -a ?client.php?
Interactive mode enabled
Buffer Data:?connect
Writing to Socket
sent to server:This data will Send to server!
?response from server was:Thank you client, you data Information Received
?
8、回到服務(wù)端上查看接收到的信息。
#/usr/local/php/bin/php -a /home/server.php
Interactive mode enabled
Socket connected
send data to client
Wrote to socket
Buffer:?This data will Send to server!
?
9、參考資料
socket_create()函數(shù)需要三個(gè)參數(shù):一個(gè)協(xié)議、一個(gè)socket類(lèi)型、一個(gè)公共協(xié)議。socket_create()函數(shù)運(yùn)行成功返回一個(gè)包含socket的資源類(lèi)型,如果沒(méi)有成功則返回false。
Socket函數(shù)
函數(shù)名????? 描述
socket_accept()??? 接受一個(gè)Socket連接
socket_bind()???? 把socket綁定在一個(gè)IP地址和端口上
socket_close()???? 關(guān)閉一個(gè)socket資源
socket_connect()??? 開(kāi)始一個(gè)socket連接
socket_create()??? 產(chǎn)生一個(gè)socket,相當(dāng)于產(chǎn)生一個(gè)socket的數(shù)據(jù)結(jié)構(gòu)
socket_listen()???? 監(jiān)聽(tīng)由指定socket的所有連接
socket_read()???? 讀取指定長(zhǎng)度的數(shù)據(jù)
socket_readv()???? 讀取從分散/聚合數(shù)組過(guò)來(lái)的數(shù)據(jù)
socket_send()???? 這個(gè)函數(shù)發(fā)送數(shù)據(jù)到已連接的socket
socket_write()???? 寫(xiě)數(shù)據(jù)到socket緩存
socket_writev()??? 寫(xiě)數(shù)據(jù)到分散/聚合數(shù)組
?
參考文檔:http://blog.51yip.com/php/673.html
轉(zhuǎn)載于:https://www.cnblogs.com/caicaizi/p/7844803.html
總結(jié)
以上是生活随笔為你收集整理的PHP-Socket服务端客户端发送接收通信实例详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 结对-贪吃蛇-项目进度
- 下一篇: 简单的链式语法及实际运用(链式编程的基本