PHP+Socket聊天室(telnet命令调试)

class socket
{
    private $_socket;
    private $_domain = AF_INET;
    private $_type = SOCK_STREAM;
    private $_protocol = SOL_TCP;
    private $_clients = [];
    private $_max_clients = 10;

    public function __construct()
    {
        if (!extension_loaded('sockets')) {
            die('the sockets extension is not loaded!');
        }
        if (($this->_socket = $this->create($this->_domain, $this->_type, $this->_protocol)) < 0) {
            $this->error($this->_socket);
        }
    }

    public function start($ip, $port)
    {
        if (($res = $this->set_option()) < 0) {
            $this->error($res);
        }
        if (($res = $this->bind($ip, $port)) < 0) {
            $this->error($res);
        }
        if (($res = $this->listen(5)) < 0) {
            $this->error($res);
        }
        #使用非阻塞模式
        socket_set_nonblock($this->_socket);
        echo "listen on port " . $port . "..." . PHP_EOL;
        $clients = array($this->_socket);
        while (true) {
            $this->_clients = $clients;
            $write = [];
            $except = [];
            if (socket_select($this->_clients, $write, $except, 0) < 1) {
                continue;
            }

            if (in_array($this->_socket, $this->_clients)) {
                $clients[] = $connection = $this->connect();
//                if (($clients + 1) > $this->_max_clients) {
//                    echo "Too many clients..." . PHP_EOL;
//                } else {
                    $this->send($connection, "welcome!\nthere are " . (count($clients) - 1) . " client here\n");
                    socket_getpeername($connection, $client_ip);
                    echo "new client connected:$client_ip\n";
                    $key = array_search($connection, $this->_clients);
                    unset($this->_clients[$key]);
//                }
            }

            foreach($this->_clients as $client){
                $receive = $this->receive($client);
                if($receive===false){
                    $key=array_search($client, $clients);
                    unset($clients[$key]);
                    echo "client disconnected.\n";
                    continue;
                }
                $receive = trim($receive);
                if(!empty($receive)){
                    foreach($clients as $send_socket){
                        if($send_socket==$this->_socket||$send_socket==$client){
                            continue;
                        }
                        $this->send($send_socket, $this->_socket .">".$client.">"."$receive\n");
                    }
                }
            }
        }
        $this->close();
    }

    public function bind($ip, $port)
    {
        socket_bind($this->_socket, $ip, $port);
    }

    public function listen($max_clients)
    {
        socket_listen($this->_socket, $max_clients);
    }

    public function connect()
    {
        return socket_accept($this->_socket);
    }

    public function send($connection, $msg)
    {
        socket_write($connection, $msg);
    }

    public function receive($client)
    {
        return socket_read($client, 819292, PHP_NORMAL_READ);
    }

    public function error($resource)
    {
        echo socket_strerror($resource) . PHP_EOL;
    }

    public function close()
    {
        socket_close($this->_socket);
    }

    public function create($domain = AF_INET, $type = SOCK_STREAM, $protocol = SOL_TCP)
    {
        return socket_create($domain, $type, $protocol);
    }

    public function set_option(){
        socket_set_option($this->_socket,SOL_SOCKET,SO_REUSEADDR,1);
    }
}


demo

ini_set("display_errors", 1);
include_once INC_PATH . "class/socket.class.php";
$socket = new socket();
$socket->start("192.168.2.113", 1371);

PHP+Socket聊天室(telnet命令调试)_第1张图片

你可能感兴趣的:(PHP+Socket聊天室(telnet命令调试))