unix网络io模型之阻塞模型
Posted weixin_44183558
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unix网络io模型之阻塞模型相关的知识,希望对你有一定的参考价值。
自己手写的五种网络模型,欢迎各路大神提意见和建议;
环境准备:php7.4,swoole4.8.2,(这里我用的是mac)
homebrew安装:mac下国内安装Homebrew教程 - 阿圣枫 - 博客园
php安装:mac下安装php7.4+mysql5.7+nginx环境_且行好事莫问前程-CSDN博客
swoole安装:Swoole4 文档,我用的是pecl,mac安装可能会出现小问题,可以评论留言
这里使用composer来管理我们的命令空间
composer安装:Composer 安装与使用 | 菜鸟教程,找到对应的安装方式
创建一个新的文件夹,执行composer init初始化一下;(一直回车,没有信息的要填一下信息)
初始化成功,生成了以下文件和文件夹
我这里修改了composer.json里的命名空间,需要执行composer dump-autoload命令,重新生成autoload文件,不然会找不到类
先创建下图的文件和文件夹
首先是workerbase.php是一个抽象基础类,定义一些基本的方法
<?php
namespace Ztms;
/**
* 基础抽象类
*/
abstract class WorkerBase
protected $server;
protected $events = [];
protected $config;
protected $type = "tcp";
public function __construct($host, $port)
//建立socket
$this->server = stream_socket_server("tcp://".$host.":".$port);
// echo "tcp://".$host.":".$port."\\n";
var_dump("tcp://".swoole_get_local_ip()['en0'].":".$port."启动服务");
/**
* 不同的模型实现不一样
* @var [type]
*/
protected abstract function accept();
/**
* 添加事件
* @method on
* @param [type] $event [description]
* @param [type] $call [description]
* @return [type] [description]
*/
public function on($event, $call)
$this->events[strtolower($event)] = $call;
public function set()
/**
* 发送信息
* @method send
* @param [type] $client [description]
* @param [type] $data [description]
* @return [type] [description]
*/
public function send($client, $data)
fwrite($client, $data);
// \\fread
public function close($client)
\\fclose($client);
public function start()
// var_dump($this->events);
// var_dump($this->events, "输出服务注册的事件");
$this->accept();
worker.php就是阻塞模型,这while是让他一直保持监听状态
<?php
namespace Ztms\\Blocking;
use Ztms\\WorkerBase;
/**
* 阻塞模型
*/
class Worker extends WorkerBase
protected function accept()
while (true)
// 监听是否存在连接
$conn = stream_socket_accept($this->server);
if (!empty($conn))
// 触发建立连接事件
$this->events['connect']($this, $conn);
// 接收服务的信息
$data = fread($conn, 65535);
$this->events['receive']($this, $conn, $data);
if (!empty($conn) && \\get_resource_type($conn) == "Unknown")
// 断开连接
$this->events['close']($this, $conn);
server.php是服务端
<?php
require_once __DIR__."/../../vendor/autoload.php";
use Ztms\\Blocking\\Worker;
$server = new Worker('0.0.0.0', 9500);
$server->on('connect', function($server, $client)
echo "1我们连接成功啦"."\\n";
);
$server->on('receive', function(Worker $server, $client, $data)
//接受客户端消息
echo '2'.$data."\\n";
//服务端发送给客户端
$server->send($client, "3滚,你这个渣男,你对别人也是这么说的吧");
sleep(20);//为了更好的看到效果,这里假装睡眠20秒
$server->close($client);
);
$server->on('close', function($server, $client)
echo "4客户端只好断开了连接"."\\n";
);
$server->start();
client.php是客户端
<?php
require_once __DIR__."/../../vendor/autoload.php";
// 连接服务端
$fp = stream_socket_client("tcp://192.168.0.102:9500");
fwrite($fp, "一直有句话想对你说 做我的女朋友吧!");
var_dump(fread($fp, 65535));
ok,现在我们启动一下服务,进入test/blocking目录执行php server.php
服务启动成功,再打开两个窗口,都进入到test/blocking目录,同时执行time php client.php
可以看到右上角的客户端已经收到服务端发来的消息了,服务端我们已经设置了20秒关闭连接,所以右下角的客户端必须等待右上角客户端的连接关闭才能执行,右上的客户端已经执行完毕了,就开始执行右下角的,如图
到此已经测试成功了,在这里我只想说,阻塞模型并不是渣男,他的确是对很多人说了做我女朋友吧,但是都是在分手之后说的,所以他并不是一个渣男。
以上是关于unix网络io模型之阻塞模型的主要内容,如果未能解决你的问题,请参考以下文章