• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

PHP网络编程 之Accept 阻塞模型的介绍

php 搞代码 3年前 (2022-01-21) 20次浏览 已收录 0个评论
本篇文章给大家分享的内容是关于PHP网络编程 之Accept 阻塞模型的介绍,内容很详细,有需要的朋友可以参考一下,希望可以帮助到大家。

Accept 阻塞模型是一种相对古老的模型,不过里面蕴含了许多有趣的知识,比如阻塞/非阻塞、锁、超时重传…

服务端程序 acceptSever.php

<?phpset_time_limit(0);  # 设置脚本执行时间无限制class SocketServer {    private static $socket;    function SocketServer($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)");                        while ($conn = stream_socket_accept($socket, -1)) { // 这样设置不超时才有用            static $id = 0; # 进程 id            static $ct = 0; # 接收数据的长度              $ct_last = $ct;             $ct_data = ''; # 接受的数据            $buffer = '';  # 分段读取数据                    $id++;             echo "Client $id come" . PHP_EOL;                        # 持续监听            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 . PHP_EOL;            fwrite($conn, "Received $ct_size byte data./r/n");            fclose($conn);        }                fclose($socket);    }}new SocketServer(2000);

客户端程序 acceptClient.php

<?php# 日志记录function debug ($msg){    error_log($msg, 3, './socket.log');}if ($argv[1]) {        $socket_client = stream_socket_client('tcp://0.0.0.0:2000', $errno, $errstr, 30);        /*    设置脚本为非阻塞    */#    stream_set_blocking($sock<mark>(本文来)源gaodaimacom搞#^代%!码&网(</mark><pre>搞gaodaima代码

et_client, 0); /* 设置脚本超时时间 */# 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); echo 'W'; // 打印写的次数# debug(fread($socket_client, 1024)); // 将产生死锁,因为 fread 在阻塞模式下未读到数据时将等待 } fwrite($socket_client, "/r/n"); // 传输结束符 # 记录日志 debug(fread($socket_client, 1024)); fclose($socket_client); }}else { // $phArr = array();// for ($i = 0; $i < 10; $i++) {// $phArr[$i] = popen("php ".__FILE__." '{$i}:test'", 'r');// }// foreach ($phArr as $ph) {// pclose($ph);// } for ($i = 0; $i < 10; $i++) { system("php ".__FILE__." '{$i}:test'"); # 这里等于 php "当前文件" "脚本参数" }}

代码解析

首先,解释一下以上的代码逻辑:客户端 acceptClient.php 循环发送数据,最后发送结束符;服务端 accept Server.php 使用 accept 阻塞方式接收 socket 连接,然后循环接收数据,直到收到结束符,返回结果数据(接收到的字节数)客户端收到服务器返回的数据,写入日志。虽然逻辑很简单,但是其中有几种情况很值得分析一下:


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:PHP网络编程 之Accept 阻塞模型的介绍
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址