首頁 後端開發 php教程 PHP 編寫基本的 Socket 程式

PHP 編寫基本的 Socket 程式

Nov 18, 2019 pm 02:11 PM
php

告誡年輕人

空想是沒有用的,個人的能力來自每一天的努力,而不是一步登天,不要畏懼任何新的知識,水滴石穿,總有一天會柳暗花明。

我的目的

因為在以後的學習中,我可能會用到網路方面的內容,但同時很多寫PHP 的coder 都沒寫過socket程序,但是肯定聽說過它,也肯定聽說過網絡編程這個詞,所以為了今後的學習,我打算在這裡先簡單的講解下相關知識,本篇博文自帶實例程序,代碼託管在碼雲(php-socket-base-code:https://gitee.com/obamajs/php-socket-base-code),你只需要下載下來,設定相關環境,按照指示即可運作。

環境配置

socket 程式設計需要開啟php 的socket 擴展,我使用的電腦是windows,所以這裡你只需要打開php.ini 文件,找到這一行去掉註解就可以了

extension=sockets
登入後複製

官方文件

php 的socket 程式設計的官方網址為:php socket(https://www.php.net/manual/ en/book.sockets.php)

服務端程式設計

socket 程式設計遵循一定的程式設計步驟,這幾個步驟缺一不可,客戶端和服務端程式設計有所區別,我們先來看看服務端。

PHP 編寫基本的 Socket 程式

建立套接字

套接字屬於系統資源,我們先呼叫socket_create 方法(參考官方文件:https: //www.php.net/manual/en/function.socket-create.php),呼叫如下:

$this->socket_handle = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (!$this->socket_handle) {
      //创建失败抛出异常,socket_last_error获取最后一次socket操作错误码,socket_strerror打印出对应错误码所对应的可读性描述
     throw new Exception(socket_strerror(socket_last_error($this->socket_handle)));
} else {
          echo "create socket successful\n";
}
登入後複製

第一個參數指定了,目前套接字是採用ipv4 還是ipv6,如果是前者的話,那麼傳遞AF_INET,否則AF_INET6,當然還有一種類型,就是AF_UNIX,這個暫時不討論,我們一般選擇AF_INET(ipv6 不是很普及)。

第二個參數,指定了協定的類型,一般選擇TCP 或是UDP,TCP 是可靠的串流(生活當中用的最為廣泛,保證了可靠性和安全性),UDP 則不是,這個參數一般選擇TCP。

第三個如果你之前選擇了 TCP,那麼它就是 SOL_TCP,否則就是 SOL_UDP。

綁定位址和連接埠號碼

因為一個主機可能存在多個ip 位址,所以你需要指定你的socket 監聽的是哪一個,常用的值為127.0.0.1,或是監聽所有位址0.0.0.0,那麼這裡可能有人不懂了,127.0.0.1 和0.0.0.0 有啥差別呢? 127.0.0.1 只是一個回環地址,只能用於本機訪問,說白了就是自己玩自己的,因為這個ip 不對外部開放,所以有人也就無法訪問這個地址,所以如果你的伺服器地址設定為127.0. 0.1,別人想要訪問,只能去屎吧。

0.0.0.0 嚴格來說不算是 ip 位址,它的意思是本機的所有 IP 位址,都是我的,哈哈。

明白了上面這個,我們來看這個呼叫的程式碼

if (!socket_bind($this->socket_handle, $this->addr, $this->port)) {
         throw new Exception(socket_strerror(socket_last_error($this->socket_handle)));
    } else {
         echo "bind addr successful\n";
 }
登入後複製

是不是很簡單,第一個參數就是socket_create 回傳的結果,第二個參數就是位址了,上面已經說過了,第三個參數是埠號。

監聽套接字

經過上面的這些步驟,我們只是創建了一個套接字並且給它綁定了連接埠號碼和位址,但是系統怎麼知道它是監聽套接字呢?所以呢,我們的事情還沒做完,所以我們得告訴它啊,別告訴我你和系統心有靈犀啊! ! !

if (!socket_listen($this->socket_handle, $this->back_log)) {
      throw new Exception(socket_strerror(socket_last_error($this->socket_handle)));
  } else {
      echo "socket  listen successful\n";
 }
登入後複製

第二個參數值得說明一哈,請聽我細細道來,對於linux 系統中的每一個進程而言,系統都維護著待處理套接字的隊列(先進先出,總得講個先來後到吧),上層程式處理業務邏輯總得需要時間吧,所以讓你你等你就等著嗆。那麼這個隊列的大小設定為多大呢?它的值就是這第二個參數,那我是不是可以設​​定的很大呢?騷年,你想太多了吧?不同的系統這個值有所不同,別說我忽悠你,看下面。

The maximum number passed to the backlog parameter highly depends on the underlying platform. On Linux, it is silently truncated to SOMAXCONN. On win32, if passed SOMAXCONN, the underlying service provider responsible for the socket will set the backlog to a maximum reasonable value. There is no standard provision to find out the actual backlog value on this platform.
登入後複製

你也不必關心這個值精確的數據,沒有什麼意義。

萬事俱備,只欠東風

經過上面的一通操作之後,我們可以開始接受來自客戶端的連接了,這個函數就更簡單了

$client_socket_handle = socket_accept($this->socket_handle);
登入後複製

這個函數的回傳值也是一個套接字句柄,所以你可以對它進行讀寫操作,在目前的實例程式中,我們做的事情很簡單,簡單到你可以懷疑人生了。

 $client_socket_handle = socket_accept($this->socket_handle);
        if (!$client_socket_handle) {
            echo "socket_accept call failed\n";
            exit(1);
        } else {
            while (true) {
                $bytes_num = socket_recv($client_socket_handle, $buffer, 100, 0);
                if (!$bytes_num) {
                    echo "socket_recv  failed\n";
                    exit(1);
                } else {
                    echo "content from client:" . $buffer . "\n";
                }
            }
        }
登入後複製

讀取套接字

以上面的範例為例,我們使用socket_recv 讀取來自客戶端的內容,這個函數很簡單,函數原型如下

socket_recv ( resource $socket , string &$buf , int $len , int $flags ) : int
登入後複製

讀取的內容會在第二個參數返回,第二個參數傳遞我們想要讀取的字元數,第四個參數可以直接設定為0,該函數的返回值為實際讀取的位元組數。

客戶端程式設計

客户端相对于服务端来说,就很简单了,流程如下

PHP 編寫基本的 Socket 程式

创建套接字前面已经讲过了,不再详述,客户端只需要连接服务器即可,函数为 socket_create,我们来看一哈在当前的例子中,我们是如何调用的。

if (!socket_connect($this->socket_handle, $this->server_addr, $this->server_port)) {
            echo socket_strerror(socket_last_error($this->socket_handle)) . "\n";
            exit(1);
        } else {
            while (true) {
                $data = fgets(STDIN);
                //如果用户输入quit,那么退出程序
                if (strcmp($data, "quit") == 0) {
                    break;
                }
                socket_write($this->socket_handle, $data);
            }
        }
登入後複製

该函数只需要指定服务器的地址和端口号即可,参数是不是很简单

练习实例

在讲解基本函数调用的时候,我就把自带程序的核心部分,复制出来了,如果要完整的程序,这里是地址(php-socket-base-code:https://gitee.com/obamajs/php-socket-base-code),代码非常简单,再次提醒,这些代码完全是用于给大家讲解基本的 socket 变成操作,为大家以后的学习打下基础,那么如何使用这个例子程序呢?

进入到命令行,开启服务器程序

php TcpServer.php,

打开另外一个命令行界面,

php TcpClient.php,

在客户端界面,输入任何文本,再输入回车,再切换到服务器界面,您将会看到客户端输入的内容

在笔者的电脑上操作实例截图如下:

PHP 編寫基本的 Socket 程式

以上是PHP 編寫基本的 Socket 程式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

適用於 Ubuntu 和 Debian 的 PHP 8.4 安裝和升級指南 適用於 Ubuntu 和 Debian 的 PHP 8.4 安裝和升級指南 Dec 24, 2024 pm 04:42 PM

PHP 8.4 帶來了多項新功能、安全性改進和效能改進,同時棄用和刪除了大量功能。 本指南介紹如何在 Ubuntu、Debian 或其衍生版本上安裝 PHP 8.4 或升級到 PHP 8.4

如何設定 Visual Studio Code (VS Code) 進行 PHP 開發 如何設定 Visual Studio Code (VS Code) 進行 PHP 開發 Dec 20, 2024 am 11:31 AM

Visual Studio Code,也稱為 VS Code,是一個免費的原始碼編輯器 - 或整合開發環境 (IDE) - 可用於所有主要作業系統。 VS Code 擁有大量針對多種程式語言的擴展,可以輕鬆編寫

在PHP API中說明JSON Web令牌(JWT)及其用例。 在PHP API中說明JSON Web令牌(JWT)及其用例。 Apr 05, 2025 am 12:04 AM

JWT是一種基於JSON的開放標準,用於在各方之間安全地傳輸信息,主要用於身份驗證和信息交換。 1.JWT由Header、Payload和Signature三部分組成。 2.JWT的工作原理包括生成JWT、驗證JWT和解析Payload三個步驟。 3.在PHP中使用JWT進行身份驗證時,可以生成和驗證JWT,並在高級用法中包含用戶角色和權限信息。 4.常見錯誤包括簽名驗證失敗、令牌過期和Payload過大,調試技巧包括使用調試工具和日誌記錄。 5.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

php程序在字符串中計數元音 php程序在字符串中計數元音 Feb 07, 2025 pm 12:12 PM

字符串是由字符組成的序列,包括字母、數字和符號。本教程將學習如何使用不同的方法在PHP中計算給定字符串中元音的數量。英語中的元音是a、e、i、o、u,它們可以是大寫或小寫。 什麼是元音? 元音是代表特定語音的字母字符。英語中共有五個元音,包括大寫和小寫: a, e, i, o, u 示例 1 輸入:字符串 = "Tutorialspoint" 輸出:6 解釋 字符串 "Tutorialspoint" 中的元音是 u、o、i、a、o、i。總共有 6 個元

您如何在PHP中解析和處理HTML/XML? 您如何在PHP中解析和處理HTML/XML? Feb 07, 2025 am 11:57 AM

本教程演示瞭如何使用PHP有效地處理XML文檔。 XML(可擴展的標記語言)是一種用於人類可讀性和機器解析的多功能文本標記語言。它通常用於數據存儲

解釋PHP中的晚期靜態綁定(靜態::)。 解釋PHP中的晚期靜態綁定(靜態::)。 Apr 03, 2025 am 12:04 AM

靜態綁定(static::)在PHP中實現晚期靜態綁定(LSB),允許在靜態上下文中引用調用類而非定義類。 1)解析過程在運行時進行,2)在繼承關係中向上查找調用類,3)可能帶來性能開銷。

什麼是PHP魔術方法(__ -construct,__destruct,__call,__get,__ set等)並提供用例? 什麼是PHP魔術方法(__ -construct,__destruct,__call,__get,__ set等)並提供用例? Apr 03, 2025 am 12:03 AM

PHP的魔法方法有哪些? PHP的魔法方法包括:1.\_\_construct,用於初始化對象;2.\_\_destruct,用於清理資源;3.\_\_call,處理不存在的方法調用;4.\_\_get,實現動態屬性訪問;5.\_\_set,實現動態屬性設置。這些方法在特定情況下自動調用,提升代碼的靈活性和效率。

PHP和Python:比較兩種流行的編程語言 PHP和Python:比較兩種流行的編程語言 Apr 14, 2025 am 12:13 AM

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

See all articles