TCP、UDP服務(wù)客戶端上一節(jié),我們學(xué)習(xí)了如何搭起簡單的 Http、TCP 以及 UDP 服務(wù)。是不是發(fā)現(xiàn)在 Swoole 中搭建這三種服務(wù)非常地簡單方便。對于 Http 客戶端來說,我們可以直接使用瀏覽器來進行測試,或者普通的 Curl、Guzzle 也可以方便地從代碼中進行 Http 的測試。因此,我們也就不會過多地說 Http 客戶端的問題。等到進階相關(guān)的文章時,我們會再看看在 協(xié)程 中的 Http 客戶端如何使用。 今天的內(nèi)容主要是針對于 TCP 和 UDP 的客戶端。上篇文章中,我們使用的是命令行的 telnet 和 nc 工具來測試這兩種服務(wù)的運行情況,今天我們直接通過 Swoole 的客戶端對象來進行測試。 TCP 客戶端在 Swoole 中,有同步阻塞客戶端和協(xié)程客戶端兩種類型的客戶端,今天我們就行來簡單地學(xué)習(xí)一下同步阻塞客戶端。 什么叫 同步阻塞 ?其實就是我們正常的那種按照前后關(guān)系順序執(zhí)行的代碼,也就是我們在傳統(tǒng)開發(fā)中寫的那種代碼。代碼是按照順序從上往下執(zhí)行的,前面的代碼沒有執(zhí)行完,后面的代碼也不會運行。如果中間遇到函數(shù),則會通過類似棧的處理方式進入函數(shù)中進行處理。從本質(zhì)上來說,其實 面向?qū)ο?這種編程方式是有部分跳出這種線性執(zhí)行代碼的模式的,但是,它還是同步執(zhí)行的。 而多線程、協(xié)程這種東西,其實就是脫離了同步阻塞問題的,關(guān)于進程、線程、協(xié)程相關(guān)的問題,我們后面有專門的文章來說明。今天大家就只需要大概了解一下就可以了?;蛘?,你把我們今天實現(xiàn)的代碼就當(dāng)做是一個 Swoole 中自帶的 Guzzle TCP/UDP 版本客戶端就好了。
實現(xiàn)一個 TCP 客戶端非常簡單,實例化一個 Swoole\Client 對象。它的構(gòu)造參數(shù)可以傳遞 SWOOLE_SOCK_TCP 或者 SWOOLE_SOCK_UDP 等內(nèi)容。從名字就可以看出,一個是 TCP 客戶端,一個是 UDP 客戶端。 接著,我們通過 connect() 方法進行連接,連接的就是本機的 TCP 端口。這里我們直接將上篇文章中的 TCP 服務(wù)啟動起來就可以了。 接著 send() 方法用于發(fā)送數(shù)據(jù)到 服務(wù)端 ,recv() 方法用于接收服務(wù)端返回的信息,最后的 close() 用于關(guān)閉客戶端句柄。 是不是非常簡單,我們運行一下。
這個打印出來的內(nèi)容,就是我們在服務(wù)端輸出的數(shù)據(jù)。相信這一塊的內(nèi)容大家應(yīng)該是沒有什么難度的。我們直接再看看 UDP 客戶端。 UDP 客戶端對于 UDP 來說,其實它的實現(xiàn)代碼和上面的 TCP 差不多,而且更加簡潔。為什么呢?我們都知道,TCP 是要建立穩(wěn)定連接的,有三次握手四次揮手的過程,這也是 TCP 的基礎(chǔ)知識。而 UDP 不需要,它不用建立穩(wěn)定的連接,所以,我們可以在 UDP 中省略掉 connect() 的步驟。
夠簡單吧?另外,我們在這里使用的是 sendto() 方法,它的作用是向任意的地址和端口發(fā)送 UDP 數(shù)據(jù)包。當(dāng)然,你在這里使用 connect() 并且通過 send() 發(fā)送 UDP 數(shù)據(jù)也是沒問題的,大家可以自己嘗試一下。
其它方法最后,我們再來看幾個客戶端對象的其它方法。
第一個 isConnected() 用于返回客戶端是否連接的布爾值。前提當(dāng)然是要調(diào)用了 connect() 并成功建立連接之后才會返回 true 。 getSocket() 用于返回一個 socket 擴展的句柄資源符,目前我們的系統(tǒng)環(huán)境中暫時沒有安裝 socket 擴展,所以這個函數(shù)還用不了。 getsockname() 用于獲取客戶端的 socket 在本地的 host 和 port 端口??梢钥吹阶⑨屩形覀兂绦蜃詣釉诒镜亻_了 47998 這個端口用于和服務(wù)端的 TCP 進行通信使用。 另外在 UDP 中,我們可以使用 getpeername() 獲得對端 socket 的 IP 地址和端口。
這個方法僅支持 UPD 連接,因為 UDP 協(xié)議通信客戶端向一臺服務(wù)器發(fā)送數(shù)據(jù)包后,可能并非由此服務(wù)器向客戶端發(fā)送響應(yīng)。可以使用 getpeername() 方法獲取實際響應(yīng)的服務(wù)器 IP 和 PORT。當(dāng)然,我們目前在本機沒有這種情況,直接返回的全是零。 總結(jié)除了上述內(nèi)容之外,還有證書相關(guān)的方法函數(shù),另外也有建立長連接的常量參數(shù),這些內(nèi)容大家可以自己在下面的官方文檔鏈接中找到,在這里我就不做過多的演示了。畢竟只是帶大家入個門,直接搬文檔可不是我的風(fēng)格。 好了,最重要的三個網(wǎng)絡(luò)服務(wù)及相關(guān)的客戶端的入門展示我們就學(xué)習(xí)完成了,下一篇文章我們將再學(xué)習(xí)一個現(xiàn)在比較流行的服務(wù)應(yīng)用,那就是 WebSocket 的使用。 測試代碼: https://github.com/zhangyue0503/swoole/blob/main/2.%E5%9F%BA%E7%A1%80/source/2.3Http%E3%80%81TCP%E3%80%81UDP%E6%9C%8D%E5%8A%A1%E5%AE%A2%E6%88%B7%E7%AB%AF.php 參考文檔: https://wiki./#/client |
|