PHP stream 学习笔记一(同步阻塞 IO 模型)

  原文http://blog.csdn.net/shagoo/article/details/6396089 
[root@localhost php]# vi server_one.php
<?php 
set_time_limit(0);
class SocketServer 
{
    private static $socket;
     public function __construct($port) 
    {
        global $errno, $errstr;
        if ($port < 1024) {
            die("Port must be a number which bigger than 1024/n");
        }
        
        $socket = stream_socket_server("tcp://0.0.0.0:{$port}", $errno, $errstr);
        if (!$socket) die("$errstr ($errno)"); 
         //stream_set_timeout($socket, -1); // 保证服务端 socket 不会超时,似乎没用:) 
        while ($conn = stream_socket_accept($socket, -1)) { // 这样设置不超时才油用 同意一个连接过来并且返回对方的socket套接字
            static $id = 0;
            static $ct = 0;
            $ct_last = $ct;
            $ct_data = '';
            $buffer = '';
            $id++; // increase on each accept
            echo "Client $id come./n";
            while (!preg_match('/(\/r)?\/n/', $buffer)) { // 没有读到结束符,继续读
//                if (feof($conn)) break; // 防止 popen 和 fread 的 bug 导致的死循环
                $buffer = fread($conn, 1024); 
                echo 'R'.PHP_EOL; // 打印读的次数
                $ct += strlen($buffer);
                $ct_data .= preg_replace('/\/r?\/n/', '', $buffer);
            }

            $ct_size = ($ct - $ct_last) * 8;
            echo "[$id] " . __METHOD__ . " > " . $ct_data . "/n".PHP_EOL;
            fwrite($conn, "Received 我是服务器我刚接收到你发的数据了大小为  $ct_size byte data ". "/r/n");
                       echo '那个连上我的人我给你写回复了';
            fclose($conn);
        }
        
        fclose($socket);
    }
}
$a = new SocketServer(2000);

[root@localhost php]#php server_one.php



[root@localhost php]# vi client_one.php
<?php 
function debug ($msg)  
{  
    echo $msg;  
    error_log($msg."\r\n", 3, '/tmp/tmp_socket.log');  
}

if ($argv[1])
{
    $socket_client = stream_socket_client('tcp://0.0.0.0:2000', $errno, $errstr, 30);   
    stream_set_blocking($socket_client, 0);  // 如果模式是0,给定流将转向非阻塞模式 1 阻塞模式
    stream_set_timeout($socket_client, 0, 100000);  //第二个参数 是否秒的超时设置  第三个参数 时间数   默认微秒 

    if (!$socket_client) {
        die("$errstr ($errno)");  
    } else {
        $msg = trim($argv[1]);  
        for ($i = 0; $i < 10; $i++) {
            $res = fwrite($socket_client, "$msg($i)");  
            usleep(100000);  //以指定的微秒数延迟执行   1微秒(micro second)是百万分之一秒。  
            echo 'W'; // 打印写的次数  
           //debug(fread($socket_client, 1024)); //将产生死锁,因为 fread 在阻塞模式下未读到数据时将等待  
        }
        fwrite($socket_client, "/r/n"); // 传输结束符  
       sleep(2);  //注意这里不睡2秒不写日志
        debug(fread($socket_client, 10024));  
        fclose($socket_client);  
    }
}






开启三个客户端重复如下命令     这时候服务端响应情况 结果只提供一个人的响应服务
[root@localhost php]#telnet 127.0.0.1 2000
crtl + ]
telnet> 直接回车
1
23
234
abc

 

posted @ 2016-04-04 18:36  诗兄  阅读(1016)  评论(0编辑  收藏  举报