socket通常也稱為"套接字",用於描述IP位址和端口,是一個通訊鏈的句柄。應用程式通常透過"套接字"向網路發出請求或應答網路請求。 socket既不是程序,也不是協議,其只是作業系統提供的通訊層的一組抽象API。前面章節介紹了一些php socket的常用重要的函數,在socket通訊中就會有使用。
通訊需要服務端和客戶端組成:
服務端:使用php初始化socket然後綁定一個端口,對端口進行監聽。呼叫accept阻塞,等待客戶端連線。
客戶端:客戶端初始化一個socket,然後連接伺服器,如果連線成功,這時客戶端與伺服器端的連線就建立了。客戶端發送資料請求,伺服器端接收請求並處理請求,然後把回應資料傳送給客戶端,客戶端讀取數據,最後關閉連接,一次互動結束。
客戶端—服務端是可以彼此互動的應用程式。客戶端和服務端之間的互動需要連線。 Socket程式設計負責的就是為應用程式之間建立可進行互動的連結。
Socket連接過程
根據連接啟動的方式以及本地套接字要連接的目標,套接字之間的連接過程可以分為三個步驟:伺服器監聽,客戶端請求,連線確認。
(1)伺服器監聽:是伺服器端套接字並沒有定位特定的客戶端套接字,而是處於等待連線的狀態,即時監控網路狀態。
(2)客戶端請求:是指由客戶端的套接字提出連線請求,要連線的目標是伺服器端的套接字。為此,客戶端的套接字必須先描述它要連接的伺服器的套接字,指出伺服器端套接字的位址和連接埠號,然後就向伺服器端套接字提出連接請求。
(3)連線確認:是指當伺服器端套接字監聽到或說接收到客戶端套接字的連線請求,它就回應客戶端套接字的請求,建立一個新的線程,把伺服器端套接字的描述發給客戶端,一旦客戶端確認了此描述,連線就建立好了。而伺服器端套接字繼續處於監聽狀態,繼續接收其他客戶端套接字的連線請求。
socket原理可以參考下面的流程圖:
#下面透過一個服務端--客戶端的程式碼實例來簡單實作一下socket通信整個過程
1. 其服務端程式碼:
<?php set_time_limit(0); //限制执行时间 0为不限制 $ip = '127.0.0.1'; $port = 8001;//端口 /** socket通信整个过程 socket_create //创建一个套接字 socket_bind //给套接字绑定 ip 和端口 socket_listen //监听套接字上的连接 socket_accept //接受一个socket连接 socket_read //接收客户端 发送的数据 socket_write //将数据写到 socket 缓存 向客户端发送 socket_close //关闭套接字资源 */ 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 { //发到客户端 $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 文件,運行後,應該看不見結果, 可以使用 #netstat -ntlp 查看8001 連接埠是否已被佔用。參見下圖。
2. 其客戶端程式碼:
<?php error_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连接 连接服务端 socket_write //将数据写入缓存 向服务端发送 socket_read// 读取服务端的结果 socket_close // 关闭套接字资源 */ $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 "发送到服务器信息成功!\n"; echo "发送的内容为:<font color='red'>$in</font> <br>"; } while($out = socket_read($socket, 8192)) { echo "接收服务器回传信息成功!\n"; echo "接受的内容为:",$out; } echo "关闭SOCKET...\n"; socket_close($socket); echo "关闭OK\n"; ?>
在看看服務端的視窗結果:
說明: PHP 語言的特性決定了php 在這方面它只適合做客戶端,不適合做服務端。
【相關教學推薦】
###以上是如何實現簡單的php socket通信的詳細內容。更多資訊請關注PHP中文網其他相關文章!