06.网络io模型及阻塞模型

1.stream-socket简单体验 与 socket连接处理的阻塞状态

函数作用参考地址
stream_socket_server创建一个sockethttps://www.php.net/manual/zh/function.stream-socket-server.php
stream_socket_accept用于接收连接https://www.php.net/manual/zh/function.stream-socket-accept.php
fread函数读取文件https://www.w3school.com.cn/php/func_filesystem_fread.asp
is_callable检测是否存在可运行的函数https://www.php.net/manual/zh/function.is-callable.php
call_user_func调用某一个方法https://www.php.net/manual/zh/function.call-user-func.php

实例代码:
stream_socket_server.php

<?php
$host = "tcp://0.0.0.0:9501";
// 创建socket服务
$server = stream_socket_server("tcp://0.0.0.0:9501");
echo $host."\n";

// 建立与客户端的连接
// 服务就处于一个挂起的状态 -》 等待连接进来并且呢创建连接
// stream_socket_accept 是阻塞
// 监听连接 -》 可以重复监听
while (true) {
    $client = @stream_socket_accept($server);
    sleep(3);
    var_dump(fread($client, 65535));
    fwrite($client, "server hellow");
    fclose($client);
    var_dump($client);
}

stream_socket_client.php

<?php
// 是建立连接
$client = stream_socket_client("tcp://127.0.0.1:9501");
$new = time();
// 给socket通写信息
fwrite($client, "hello world");
// 读取信息
var_dump(fread($client, 65535));
// 关闭连接
fclose($client);

echo "\n".time()- $new;
   // while (!feof($fp)) {
   //     echo fgets($fp, 1024);
   // }
   // fclose($fp);

2.5大io模型

1.1. 阻塞式I/O模型(blocking i/o)
**1.2. 非阻塞式I/O模型(non-blocking i/o)
1.3. I/O复用模型(i/o multiplexing)
1.4 信号驱动式I/O模型(signal-driven i/o)
1.5 异步I/O模型(asynchronous i/o)**

3. 编辑io模型准备

为了更好地理解,网络编程, 写出高性能的服务; 那么首先我们需要了解在进程阻塞的网络服务器的实现过程; 这里我们以原生的代码诠释。
为了与项目更好的阅读,方便编辑这里使用一下composer来加载命名规则及其诠释代码的目录结构。

io-
- src
    - Blocking
    - NonBlocking
    - Multiplexing
    - SingnalDriven
    - Asynchronous
- test
    - blocking
    - nonBlocking
    - multiplexing
    - singnal-driven
    - asynchronous
- vendor
- composer.json

构建项目:

$ io>composer init
Welcome to the Composer config generator
This command will guide you through creating your composer.json config.
Package name (<vendor>/<name>) [shineyork/io]: shineyork/io
Description []:
Author [, n to skip]: shineyork <shineyork@sixstaredu.com>
Minimum Stability []:
Package Type (e.g. library, project, metapackage, composer-plugin) []: library
License []: MIT
Define your dependencies.
Would you like to define your dependencies (require) interactively [yes]?
Search for a package:
Would you like to define your dev dependencies (require-dev) interactively [yes]?
Search for a package:
{
"name": "shineyork/io",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "shineyork",
"email": "shineyork@sixstaredu.com"
}
],
"require": {}
}
Do you confirm generation [yes]? yes

然后修一下composer.json即可

{
    "name": "shineyork/io",
    "type": "library",
    "license": "MIT",
    "authors": [
        {
            "name": "shineyork",
            "email": "shineyork@sixstaredu.com"
        }
    ],
    "autoload":{
        "psr-4":{
            "ShineYork\\Io\\":"./src/"
        }
    },
    "require": {}
}
  1. 阻塞io模型

iosrcBlockingWorker.php

    <?php
    namespace ShineYork\Io\Blocking;
    // 这是等会自个要写的服务
class Worker
{
        // 自定义服务的事件注册函数,
        // 这三个是闭包函数
        public $onReceive = null;
        public $onConnect = null;
        public $onClose = null;

        // 连接
        public $socket = null;

        public function __construct($socket_address){
            $this->socket = stream_socket_server($socket_address);
            echo $socket_address."\n";
        }

        // ...
        // stream_select
        public function on(){

        }

        // 需要处理事情
        public function accept(){
            // 接收连接和处理使用
            while (true) {
                $client = @stream_socket_accept($this->socket);
                // is_callable判断一个参数是不是闭包
                if (is_callable($this->onConnect)) {
                    // 执行函数
                    ($this->onConnect)($this, $client);
                }
                // tcp 处理 大数据 重复多发几次
                // $buffer = "";
                // while (!feof($client)) {
                //    $buffer = $buffer.fread($client, 65535);
                // }
                $data = fread($client, 65535);
                if (is_callable($this->onReceive)) {
                    ($this->onReceive)($this, $client, $data);
                }
                // 处理完成之后关闭连接
                fclose($client);
            }
        }

        // 发送信息
        public function send($conn, $data){
            fwrite($conn, $data);
        }

        // 启动服务的
        public function start(){
            $this->accept();
        }
}

iotestblockingserver.php

<?php
require __DIR__.'/../../vendor/autoload.php';
use ShineYork\Io\Blocking\Worker;
$host = "tcp://0.0.0.0:9000";
$server = new Worker($host);
// $server->onConnect = function($socket, $client){
//     echo "有一个连接进来了\n";
//     var_dump($client);
// };
// 接收和处理信息
$server->onReceive = function($socket, $client, $data){
    echo "给连接发送信息\n";
    $socket->send($client, "hello world client \n");
    // fwrite($client, "server hellow");
};
$server->start();

王如棋博客
请先登录后发表评论
  • 最新评论
  • 总共0条评论