天天看点

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同步阻塞客户端