socket服务的模型以及实现(1)–单进程阻塞模型

这里我们只以tcp服务举例,协议以换行符举例.我们先看最简单的单进程阻塞模型

首先一个socket服务的代码如下:

<?php
/**
 * 单进程阻塞式--同时只能处理一个连接
 */
class Xtgxiso_server
{
    public $socket = false;
    public $onConnect = null;
    public $onMessage = null;
    public $onClose = null;

    function __construct($host="0.0.0.0",$port=1215)
    {
        $this->socket = stream_socket_server("tcp://".$host.":".$port,$errno, $errstr);
        if (!$this->socket) die($errstr."--".$errno);
    }

    public function run(){
        while ( 1 ) {
            echo  "waiting...\n";
            $conn = stream_socket_accept($this->socket, -1);
            if ( !$conn ){
                continue;
            }
            if($this->onConnect)
            {
                call_user_func($this->onConnect, $conn);
            }
            $receive = '';
            $buffer = '';
            while ( 1 ) {
                $buffer = fread($conn, 3);
                if($buffer === '' || $buffer === false)
                {
                    if ( $this->onClose ){
                        call_user_func($this->onClose, $conn);
                    }
                    break;
                }
                $pos = strpos($buffer, "\n");
                if($pos === false)
                {
                    $receive .= $buffer;
                    //echo "received:".$buffer.";not all package,continue recdiveing\n";
                }else{
                    $receive .= trim(substr ($buffer,0,$pos+1));
                    $buffer = substr($buffer,$pos+1);
                    if($this->onMessage)
                    {
                        call_user_func($this->onMessage, $conn, $receive);
                    }
                    switch ( $receive ){
                        case "quit":
                            echo "client close conn\n";
                            fclose($conn);
                            break 2;
                        default:
                            //echo "all package:\n";
                            //echo $receive."\n";
                            break;
                    }
                    $receive='';
                }
            }
        }
        fclose($socket);
    }
}
$server =  new Xtgxiso_server();

$server->onConnect = function($conn){
    echo "onConnect -- accepted " . stream_socket_get_name($conn,true) . "\n";
    fwrite($conn,"conn success\n");
};

$server->onMessage = function($conn,$msg){
    echo "onMessage --" . $msg . "\n";
    fwrite($conn,"received ".$msg."\n");
};

$server->onClose = function($conn){
    echo "onClose --" . stream_socket_get_name($conn,true) . "\n";
    fwrite($conn,"onClose "."\n");
};

$server->run();

大家可以用telnet命令来测试,这也是用换行符协议的原因,方便测试。可以很明显的看到,这个服务同时只能处理一个连接,肯定不会用人用这种方式来实现socket服务的

此条目发表在 好文推荐, 网站开发, 网站架构 分类目录,贴了 标签。将固定链接加入收藏夹。

评论功能已关闭。