天天看點

swoole學習筆記——TCP同步阻塞用戶端

一、官方案例了解

Client端建立

Client提供了TCP/UDP socket的用戶端的封裝代碼,使用時僅需 new Swoole\Client 即可。

同步阻塞用戶端

$ 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();⑥
           

① 函數原型:

swoole_client->__construct(int $ sock_type, int $ is_sync = SWOOLE_SOCK_SYNC, string $ key);
           

• $ sock_type表示socket的類型,如TCP/UDP

• 使用$ sock_type | SWOOLE_SSL可以啟用SSL加密

• $ is_sync表示同步阻塞還是異步非阻塞,預設為同步阻塞

• $ key用于長連接配接的Key,預設使用IP:PORT作為key。相同key的連接配接會被複用

swoole_client構造函數參數

• SWOOLE_SOCK_TCP 建立tcp socket

• SWOOLE_SOCK_TCP6 建立tcp ipv6 socket

• SWOOLE_SOCK_UDP 建立udp socket

• SWOOLE_SOCK_UDP6 建立udp ipv6 socket

• SWOOLE_SOCK_UNIX_DGRAM 建立unix dgram socket

• SWOOLE_SOCK_UNIX_STREAM 建立unix stream socket

• SWOOLE_SOCK_SYNC 同步用戶端

• SWOOLE_SOCK_ASYNC 異步用戶端

是以在官方案例第一步輸入構造函數SWOOLE_SOCK_TCP 參數,就可以建立tcp對象

② 連接配接到遠端伺服器,函數原型:

bool $swoole_client->connect(string $host, int $port, float $timeout = 0.5, int $flag = 0)
           

connect方法接受4個參數:

• $ host是遠端伺服器的位址,1.10.0或更高版本已支援自動異步解析域名,$ host可直接傳入域名

• $ port是遠端伺服器端口

• $ timeout是網絡IO的逾時,包括connect/send/recv,機關是s,支援浮點數。預設為0.5s,即500ms

• $ flag參數在UDP類型時表示是否啟用udp_connect 設定此選項後将綁定$ host與$ port,此UDP将會丢棄非指定host/port的資料包。

• $ flag參數在TCP類型,$ flag=1表示設定為非阻塞socket,connect會立即傳回。如果将$ flag設定為1,那麼在send/recv前必須使用swoole_client_select來檢測是否完成了連接配接

③ 發送資料到遠端伺服器,必須在建立連接配接後,才可向Server發送資料。函數原型:

int $swoole_client->send(string $data);
           

• $ data參數為字元串,支援二進制資料

• 成功發送傳回的已發資料長度

• 失敗傳回false,并設定$ swoole_client->errCode

④ recv方法用于從伺服器端接收資料。接受2個參數。函數原型為:

//低于1.7.22
string $swoole_client->recv(int $size = 65535, bool $waitall = 0);
//1.7.22或更高
string $swoole_client->recv(int $size = 65535, int $flags = 0);
           

• $ size,接收資料的緩存區最大長度,此參數不要設定過大,否則會占用較大記憶體

• $ waitall,是否等待所有資料到達後傳回

如果設定了$ waitall就必須設定準确的$size,否則會一直等待,直到接收的資料長度達到 $ size

未設定 $ waitall=true時, $ size最大為64K

如果設定了錯誤的 $ size,會導緻recv逾時,傳回 false

• 成功收到資料傳回字元串

• 連接配接關閉傳回空字元串

• 失敗傳回 false,并設定 $client->errCode屬性

⑤ 關閉連接配接,函數原型為:

bool $swoole_client->close(bool $force = false);
           

操作成功傳回 true。當一個swoole_client連接配接被close後不要再次發起connect。正确的做法是銷毀目前的swoole_client,重新建立一個swoole_client并發起新的連接配接。

• 第一個參數設定為true表示強制關閉連接配接,可用于關閉SWOOLE_KEEP長連接配接

注意:同步阻塞用戶端和異步阻塞用戶端代碼編寫不一樣

二、個人案例

伺服器端代碼

//建立Server對象,監聽 127.0.0.1:9501端口
$serv = new Swoole\Server("127.0.0.1", 9501);

$serv->set(
        array(
            'worker_num'=>2,
            )

);
//監聽用戶端連接配接進入
$serv->on('Connect', function ($serv, $fd) {
    echo "第{$fd}個用戶端連接配接成功!.\n";
});

//監聽用戶端發來的資料
$serv->on('Receive', function ($serv, $fd, $reactor_id, $data) {
    $serv->send($fd, "這是fd值:{$fd}這是線程值:{$reactor_id},這是用戶端發來的值:".$data);
});

//監聽連接配接關閉事件
$serv->on('Close', function ($serv, $fd) {
    echo "伺服器端關閉成功!\n";
});

//啟動伺服器
$serv->start();

           

用戶端代碼

$client = new swoole_client(SWOOLE_SOCK_TCP);
if (!$client->connect('127.0.0.1', 9501, -1))
{
    exit("連接配接失敗!: {$client->errCode}\n");
}
fwrite(STDOUT,"請你輸入你要發給伺服器端的資料:");
$msg=trim(fgets(STDIN));
$client->send("{$msg}\n");
echo $client->recv();
$client->close();
           
·fwrite(STDOUT,"請你輸入你要發給伺服器端的資料:");
·fgets(STDIN);
這兩個函數完成了在用戶端提示使用者輸入資訊,并接受資訊的操作。
           

打開伺服器端服務

swoole學習筆記——TCP同步阻塞用戶端

打開用戶端

swoole學習筆記——TCP同步阻塞用戶端

這時候服務端出現

swoole學習筆記——TCP同步阻塞用戶端

用戶端出現

swoole學習筆記——TCP同步阻塞用戶端

這時向用戶端輸入“你好這是用戶端”,伺服器端傳回給你資料,并關閉伺服器

swoole學習筆記——TCP同步阻塞用戶端
swoole學習筆記——TCP同步阻塞用戶端