日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

【Swoole系列2.3】TCP、UDP服務(wù)客戶端

 硬核項目經(jīng)理 2022-07-11 發(fā)布于湖南

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 版本客戶端就好了。

$client = new Swoole\Client(SWOOLE_SOCK_TCP);
if (!$client->connect('127.0.0.1'9501-1)) {
   exit("connect failed. Error: {$client->errCode}\n");
}

$client->send("hello world\n");
echo $client->recv();
$client->close();

實現(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)閉客戶端句柄。

是不是非常簡單,我們運行一下。

[root@localhost source]# php 2.3Http、TCP、UDP服務(wù)客戶端.php
Server TCP:hello world

這個打印出來的內(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() 的步驟。

$client = new Swoole\Client(SWOOLE_SOCK_UDP);
$client->sendto('127.0.0.1'9501"hello world\n");
echo $client->recv();
$lient->close();

夠簡單吧?另外,我們在這里使用的是 sendto() 方法,它的作用是向任意的地址和端口發(fā)送 UDP 數(shù)據(jù)包。當(dāng)然,你在這里使用 connect() 并且通過 send() 發(fā)送 UDP 數(shù)據(jù)也是沒問題的,大家可以自己嘗試一下。

[root@localhost source]# php 2.3Http、TCP、UDP服務(wù)客戶端.php
Server UDP:hello world

其它方法

最后,我們再來看幾個客戶端對象的其它方法。

var_dump($client->isConnected()); // bool(true)
// var_dump($client->getSocket());
var_dump($client->getsockname());
//array(2) {
//    ["port"]=>
//  int(47998)
//  ["host"]=>
//  string(9) "127.0.0.1"
//}

第一個 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 地址和端口。

var_dump($client->getpeername());
//array(2) {
//    ["port"]=>
//  int(0)
//  ["host"]=>
//  string(7) "0.0.0.0"
//}

這個方法僅支持 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

    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多