Swoole 建立TCP ECHO伺服器

weixin_34232744發表於2017-04-18

開發環境搭建

1、伺服器執行環境:windows下的ubuntu虛擬機器(vmware)

使用的ubuntu版本為14.04

2、IDE:windows下使用phpstorm

推薦新增swoole-ide-helper到phpstorm的External Libraries(雙擊圖示即可新增)

3、共享資料夾

vmware開啟共享資料夾方式:

安裝Vmware-tools工具包,安裝好客戶機後,VM選單下有一個Reinstall VMware Tools,直接單擊,該工具包被載入到客戶機桌面。
命令列模式下複製安裝的tar檔案到某個資料夾或/tmp下直接解壓。
到相應的解壓目錄下執行vmware-install.pl,一路根據提示安裝即可。

右單擊你需要設定該功能的虛擬機器,單擊options,可以看到Shared Folders功能,單擊該項設定右側的Always enabled後,單擊add新增你需要設定的共享檔案所在的位置即可。

最後,啟動Ubuntu虛擬機器,進入/mnt/hgfs/目錄既可以看到共享目錄。

搭建TCP ECHO 伺服器

新建server.php

<?php

//建立Server物件,監聽 127.0.0.1:9501埠
$serv = new swoole_server("127.0.0.1", 9501); 

//監聽連線進入事件
$serv->on('connect', function ($serv, $fd) {  
    echo "Client: Connect.\n";
});

//監聽資料接收事件
$serv->on('receive', function ($serv, $fd, $from_id, $data) {
    $serv->send($fd, "Server: ".$data);
});

//監聽連線關閉事件
$serv->on('close', function ($serv, $fd) {
    echo "Client: Close.\n";
});

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


使用php server.php啟動伺服器

搭建非同步TCP客戶端

新建async_client.php檔案

<?php

$client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC);

//註冊連線成功回撥
$client->on('connect', function($cli) {
    $cli->send("hello world\n");
});

//註冊連線失敗回撥
$client->on('error', function($cli) {
    $cli->send("connect failed\n");
});

//註冊資料接受回撥
$client->on('receive', function($cli, $data) {
    echo "Received: $data\n";
    sleep(1);
    $cli->send("wake up");
});


//註冊連線關閉回撥
$client->on('close', function($cli) {
    echo "closed\n";
});

//發起連線
$client->connect('127.0.0.1', 9501, 0.5);

使用php async_client.php開啟客戶端

使用tcpdump進行抓包分析

首先開啟伺服器,開啟tcpdump監聽sudo tcpdump -iany tcp port 9501
使用telnet進行連線測試,連線上後傳送nihao,然後ctrl+]quit結束整個過程。

結果如下:

09:22:06.206068 IP localhost.36366 > localhost.9501: Flags [S], seq 3315326447, win 43690, options [mss 65495,sackOK,TS val 940145 ecr 0,nop,wscale 7], length 0
09:22:06.206140 IP localhost.9501 > localhost.36366: Flags [S.], seq 3454419015, ack 3315326448, win 43690, options [mss 65495,sackOK,TS val 940145 ecr 940145,nop,wscale 7], length 0
09:22:06.206158 IP localhost.36366 > localhost.9501: Flags [.], ack 1, win 342, options [nop,nop,TS val 940145 ecr 940145], length 0
09:22:06.206571 IP localhost.9501 > localhost.36366: Flags [P.], seq 1:7, ack 1, win 342, options [nop,nop,TS val 940145 ecr 940145], length 6
09:22:06.206648 IP localhost.36366 > localhost.9501: Flags [.], ack 7, win 342, options [nop,nop,TS val 940145 ecr 940145], length 0
09:22:10.978286 IP localhost.36366 > localhost.9501: Flags [P.], seq 1:8, ack 7, win 342, options [nop,nop,TS val 941338 ecr 940145], length 7
09:22:10.978302 IP localhost.9501 > localhost.36366: Flags [.], ack 8, win 342, options [nop,nop,TS val 941338 ecr 941338], length 0
09:22:10.978457 IP localhost.9501 > localhost.36366: Flags [P.], seq 7:23, ack 8, win 342, options [nop,nop,TS val 941338 ecr 941338], length 16
09:22:10.978462 IP localhost.36366 > localhost.9501: Flags [.], ack 23, win 342, options [nop,nop,TS val 941338 ecr 941338], length 0
09:22:17.296437 IP localhost.36366 > localhost.9501: Flags [F.], seq 8, ack 23, win 342, options [nop,nop,TS val 942918 ecr 941338], length 0
09:22:17.297329 IP localhost.9501 > localhost.36366: Flags [F.], seq 23, ack 9, win 342, options [nop,nop,TS val 942918 ecr 942918], length 0
09:22:17.297339 IP localhost.36366 > localhost.9501: Flags [.], ack 24, win 342, options [nop,nop,TS val 942918 ecr 942918], length 0


簡單分析:

一開始三次握手,建立連線:首先客戶端隨機分配一個埠來連線伺服器,Flags標誌為[S],伺服器收到以後也返回一個Flags標誌為[S]的響應,最終客戶端在傳送一個Flags標誌為[.]進行確認。此過程即為3此握手。

同理,結束連線時也要經歷3此握手,不過此時的標誌有所不同,分別為[F] [F] [.](也可能是R)。

建立連線成功後,根據指令碼,傳送了Hello\n給客戶端,在第四個請求那裡也可以看到長度為6個位元組, 型別為[P],接受到資訊以後客戶端返回確認,標誌為[.]。

然後,客戶端輸入了nihao傳送給客戶端,服務端接受到後再返回Server nihao給客戶端。


參考網站:

相關文章