首頁 > 後端開發 > php教程 > php socket程式設計常用的函數以及簡單c/s互動的實現

php socket程式設計常用的函數以及簡單c/s互動的實現

不言
發布: 2023-04-03 12:40:02
原創
1691 人瀏覽過

這篇文章給大家分享的內容是關於php socket程式設計常用的函數以及簡單c/s互動的實現,內容很詳細,有需要的朋友可以參考一下,希望可以幫助到你們。

Socket 簡介

Socket 的官方解釋:
在網路程式設計中最常用的方案就是Client/Server(客戶機/伺服器)模型。在這種方案中客戶應用程式向伺服器程式請求服務。一個服務程序通常在一個眾所周知的地址監聽對服務的請求,也就是說,服務進程一 直處於休眠狀態,直到一個客戶向這個服務的地址提出了連接請求。在這個時刻,服務程序被"驚醒"並且為客戶提供服務-對客戶的請求作出適當的反應。為了方便這種Client/Server模型的網絡編程,90年代初,由Microsoft聯合了其他幾家公司共同製定了一套WINDOWS下的網絡編程接口,即WindowsSockets規範,它不是一種網絡協議,而是一套開放的、支援多種協定的Windows下的網路程式介面。現在的Winsock已經基本上實現了與協定無關,你可以使用Winsock來呼叫多種協定的功能,但較常使用的是TCP/IP協定。 Socket實際上在電腦中提供了一個通訊端口,可以透過這個端口與任何一個具有Socket接口的電腦通訊。應用程式在網路上傳輸,接收的資訊都透過這個Socket介面來實現

我們可以簡單的把Socket 理解為一個可以連通網路上不同電腦應用程式之間的管道,把一堆資料從管道的A 端丟進去,則會從管道的B 端(同時還可以從C、D、E、F…端冒出來)。

注意:我們會在不同情境下使用不同的字詞去修飾socket,你只需要對它有個概念就好了,因為socket 本身就沒有真正意義上的實體

Socket 函數介紹

Socket 通訊依序會進行Socket 建立、 Socket 綁定、Socket 監聽、Socket 收發、Socket 關閉幾個階段,下面我們列舉出PHP 網路程式設計中最常使用也是必不可少的幾個常用的函數進行進一步的說明。

socket_create

TODO : 建立一個新的socket 資源
函數原型: resource socket_create ( int $domain , int $type , int $protocol )
它包含三個參數,分別如下:

  • domain:AF_INET、AF_INET6、AF_UNIX,AF的釋義就address family,地址族的意思,我們常用的有ipv4、ipv6

  • type: SOCK_STREAM、SOCK_DGRAM等,最常用的就是SOCK_STREAM,基於位元組流的SOCKET型,也是TCP協定使用的類型

  • protocol: SOL_TCP、SOL_UDP 這個就是具體使用的傳輸協議,一般可靠的傳輸我們選擇TCP,遊戲資料傳輸我們一般選用UDP 協定

socket_bind

TODO : 將建立的socket 資源綁定到特定的ip 位址和連接埠
函數原型: bool socket_bind ( resource $socket , string $ address [, int $port = 0 ] )

它包含三個參數,分別如下:

  • socket: 使用socket_create建立的socket 資源,可以認為是socket 對應的id

  • #address: ip 位址

  • ##port: 監聽的連接埠號,WEB 伺服器默認80埠

socket_listen

TODO : 在特定的位址下監聽socket 資源的收發操作

函數原型:
bool socket_listen ( resource $socket [ , int $backlog = 0 ] )

它包含兩個個參數,分別如下:

    ##socket: 使用
  • socket_create

    創建的socket資源

  • backlog: 等待處理連線佇列的最大長度
  • socket_accept

TODO : 監聽之後,接收一個即將來臨的新的連接,如果連接建立成功,將返回一個新的socket 句柄(你可以理解為子進程,通常父進程用來接收新的連接,子進程負責具體的通信)

函數原型:

resource socket_accept ( resource $socket )

    socket: 使用
  • socket_create

    建立的socket資源

# #socket_write

TODO : 將指定的資料傳送到對應的socket 管道
函數原型: int socket_write ( resource $socket , string $buffer [, int $length ] )

  • socket: 使用socket_create建立的socket資源

  • buffer: 寫入到socket資源中的資料

  • length: 控制寫入到socket資源中的buffer的長度,如果長度大於buffer的容量,則取buffer的容量

socket_read

TODO : 取得傳送的資料
函數原型: int socket_read ( resource $socket ,  int $length )

  • socket: 使用socket_create建立的socket資源

  • length: socket資源中的buffer的長度

socket_close

TODO: 關掉socket 資源
函數原型: void socket_close ( resource $socket )

  • socket: socket_acceptsocket_create產生的資源,不能用於stream資源的關閉

#stream_socket_server

由於創建一個SOCKET的流程總是socket、bind、listen,所以PHP提供了一個非常方便的函數一次建立、綁定連接埠、監聽連接埠

函數原型: resource stream_socket_server ( string $local_socket [, int &$errno [, string &$errstr [, int $flags = STREAM_SERVER_BIND | STREAM_SERVER_LISTEN [, resource $context ]]]]

    #local_socket: 協定名稱://位址:連接埠號碼
  • #errno: 錯誤碼
  • errstr:錯誤訊息
  • flags: 只使用該函數的部分功能
  • context: 使用
  • stream_context_create

    函數建立的資源流上下文

socket 實作C/S 互動

基於上面的函數我們可以很方便的去建構socket 通訊程式(這裡我希望讀者能單獨建立一個目錄例如

socket

因為後續我們還會建立很多檔案)我們先編輯一個服務端程式server.php,如下:<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">&lt;?php date_default_timezone_set(&quot;Asia/Shanghai&quot;); error_reporting(E_NOTICE ); /* 确保在连接客户端时不会超时 */ set_time_limit(0); $ip = &amp;#39;127.0.0.1&amp;#39;; $port = 8090; /* +------------------------------- * @socket通信整个过程 +------------------------------- * @socket_create * @socket_bind * @socket_listen * @socket_accept * @socket_read * @socket_write * @socket_close +-------------------------------- */ /*---------------- 以下操作都是手册上的 -------------------*/ if(($sock = socket_create(AF_INET,SOCK_STREAM,SOL_TCP)) &lt; 0) { echo &quot;socket_create() Why failure is:&quot;.socket_strerror($sock).&quot;\n&quot;; } if(($ret = socket_bind($sock,$ip,$port)) &lt; 0) { echo &quot;socket_bind() Why failure is:&quot;.socket_strerror($ret).&quot;\n&quot;; } if(($ret = socket_listen($sock,4)) &lt; 0) { echo &quot;socket_listen() Why failure is:&quot;.socket_strerror($ret).&quot;\n&quot;; } echo &quot;Start time:&quot;.date(&amp;#39;Y-m-d H:i:s&amp;#39;) . PHP_EOL; echo &quot;Listening at &quot;.$ip.&amp;#39;:&amp;#39;.$port.PHP_EOL; do { /* 创建新的连接 */ if (($msgsock = socket_accept($sock)) &lt; 0) { echo &quot;socket_accept() failed: reason: &quot; . socket_strerror($msgsock) . &quot;\n&quot;; break; } else { # 连接成功输出 Socket id $i = (int)$msgsock; echo &quot;welcome client $i&quot;; # 向客户端通信(反馈) $msg =&quot;连接成功!\n&quot;; socket_write($msgsock, $msg, strlen($msg)); } socket_close($msgsock); } while (true); socket_close($sock); ?&gt;</pre><div class="contentsignin">登入後複製</div></div>再編輯一個客戶端程式

client.php

,如下:<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">&lt;?php set_time_limit(0); $port = 8090; $ip = &quot;127.0.0.1&quot;; /* +------------------------------- * 客户端 socket 连接整个过程 +------------------------------- * @socket_create * @socket_connect * @socket_write * @socket_read * @socket_close +-------------------------------- */ /** * @socket_connect:客户端发起套接字连接 * @param socket resource $socket 创建的$socket资源 * @param address string SOCK_STREAM IP地址|Unix套接字 * @param port int 端口 */ /** * @socket_create:创建并返回一个套接字 * @param domain string AF_INET IPV4 网络协议 * @param type string SOCK_STREAM 全双工字节流(可用的套接字类型) * @param protocol string SOL_TCP 具体协议(IPV4下的TCP协议) * @param return 套接字 */ $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if ($socket &lt; 0) { echo &quot;socket_create() failed: reason: &quot; . socket_strerror($socket) . &quot;\n&quot;; }else { echo &quot;try to connect &amp;#39;$ip&amp;#39; port: &amp;#39;$port&amp;#39;...\n&quot;; } $result = socket_connect($socket, $ip, $port); #socket_connect的返回值应该是boolean值 if ($result &lt; 0) { echo &quot;socket_connect() failed.\nReason: ($result) &quot; . socket_strerror($result) . &quot;\n&quot;; }else { # 连接成功输出提示信息 echo &quot;connect successfully\n&quot;; # 向服务端发送数据 socket_write($socket, &quot; hello &quot;, 1024); # 获取服务端数据 $result = socket_read($socket, 1024); echo &quot;服务器回传数据为:&quot; . $result; echo &quot;CLOSE SOCKET...\n&quot;; socket_close($socket); echo &quot;CLOSE OK\n&quot;; } ?&gt;</pre><div class="contentsignin">登入後複製</div></div>然後我們打開終端機(命令列)進入檔案目錄下依序執行:

php server.php
php client.php
登入後複製

運行效果如下:

php socket程式設計常用的函數以及簡單c/s互動的實現

注意

伺服器監聽時進程是掛起的不能進行其他操作,你可能需要另起一個終端執行客戶端程式相關推薦:

PHP和MySql如何實作後台資料的讀取?(程式碼)

thinkphp5使用workerman計時器定時爬取網站內容的程式碼


以上是php socket程式設計常用的函數以及簡單c/s互動的實現的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板