<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></title> 
<link>http://jackxiang.com/index.php</link> 
<description><![CDATA[赢在IT，Playin' with IT,Focus on Killer Application,Marketing Meets Technology.]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></copyright>
<item>
<link>http://jackxiang.com/post/4803/</link>
<title><![CDATA[[个人原创]在Centos6.0机器上安装PHP的 libevent PECL Package 扩展步骤及实例，以及实现多个USB转串口的读写实践成功 ,可以用select函数。]]></title> 
<author>jack &lt;xdy108@126.com&gt;</author>
<category><![CDATA[Php/Js/Shell/Go]]></category>
<pubDate>Sat, 19 Nov 2011 04:40:49 +0000</pubDate> 
<guid>http://jackxiang.com/post/4803/</guid> 
<description>
<![CDATA[ 
	yum install libevent-dev 安装libevent<br/>yum install libevent<br/>PHP Extention: http://pecl.php.net/package/libevent/0.0.5<br/><br/><br/><br/>再就是：自己编译 http://libevent.org/<br/><br/>缘起：PHP5的先进之处在于，你可以用stream_select()处理几乎所有的stream-例如你可以通过include STDIN用它接收键盘输入并保存进数组，你还可以接收通过proc_open()打开的管道中的数据。<br/>目的：想用这个函数进行对文件句柄进行监控，其并不是想用于网络的socket句柄，为此做了如下试验：<br/>探索：能否用PHP的stream_select的方式对CentOs下的串口进行监控呢？经过一系列的研究，发现是可以进行多串口的监控的。<br/>研究： 发现会报错，stream_select(): cannot represent a stream of type dio as a select()<br/>解决： 最后，见代码吧。代码下载：<a href="attachment.php?fid=237">点击这里下载文件</a><br/>如果，你想时间更短一点，E文是这样说的：<br/>If you want to set an absolute maximum execution time for stream_select in a loop, it&#039;s important to decrement the max_time value passed to stream_select.修改了一下的情况，好像效果不明显，呵呵：<br/><a href="attachment.php?fid=238">点击这里下载文件</a><br/>完善的第三个版本备案下载，这个实现了对多个串口的同时读写。By:jack<br/><a href="attachment.php?fid=239">点击这里下载文件</a>&nbsp;&nbsp;其实主要是对这个超时机制的理解。见下面这段代码的超时：<br/><textarea name="code" class="html" rows="15" cols="100">
//cmd为要执行的程序， timeout是超时时间
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $descriptorspec = array(
&nbsp;&nbsp;&nbsp;&nbsp;0 =&gt; array(&quot;pipe&quot;, &quot;r&quot;),
&nbsp;&nbsp;&nbsp;&nbsp;1 =&gt; array(&quot;pipe&quot;, &quot;w&quot;),
&nbsp;&nbsp;&nbsp;&nbsp;2 =&gt; array(&quot;pipe&quot;, &quot;w&quot;)
&nbsp;&nbsp;&nbsp;&nbsp;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$process = proc_open($cmd, $descriptorspec, $pipes);
&nbsp;&nbsp;&nbsp;&nbsp;$stdout_str = $stderr_str = &quot;&quot;;
 
&nbsp;&nbsp;&nbsp;&nbsp;if (is_resource($process)) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//执行成功
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stream_set_blocking($pipes[1], 0);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stream_set_blocking($pipes[2], 0);&nbsp;&nbsp;//不阻塞
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fwrite($pipes[0], $stdin_str);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fclose($pipes[0]);
 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//设置超时时钟
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$endtime = time() + $timeout;
 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$timeleft = $endtime - time();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ret = stream_select(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$read = array($pipes[1],$pipes[2]),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$write = null,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$except = null,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$timeleft
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);
 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($ret === false) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$err = true;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; else if ($ret === 0) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$timeleft = 0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; else &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach ($read as $sock) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($sock === $pipes[1]) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$stdout_str .= fread($sock, 4096);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; else if ($sock === $pipes[2]) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$stderr_str .= fread($sock, 4096);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;while((feof($pipes[1]) === false &#124;&#124; feof($pipes[2]) === false) &amp;&amp; $timeleft &gt; 0);
 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fclose($pipes[1]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fclose($pipes[2]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if($timeleft &lt;= 0) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proc_terminate($process);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$stderr_str = &quot;操作已超时(&quot;.$timeout.&quot;秒)&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (isset($err) &amp;&amp; $err === true)&#123;&nbsp;&nbsp;//这种情况的出现是通过信号发送中断时产生
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proc_terminate($process);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$stderr_str = &quot;操作被用户取消&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proc_close($process);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;else &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
</textarea><br/>插曲：dio.raw://[device]<br/>for raw streams anddio.serial://[devicefor serials streams. 这两种stream有什么区别啊？用serial不行，而用raw就Ok了。但是会出现上面的报错：stream_select(): cannot represent a stream of type dio as a select()<br/>php有个libevent扩展，我觉得这个扩展应该可以有更广泛的用途，比如：<br/>(1)异步的服务器端开发框架.<br/>(2)类似unix下的tail命令行.<br/>(3)用php和ZeroMQ实现的一个事件驱动服务器端<br/>http://blog.sina.com.cn/s/blog_60b9ee7f0100qdmh.html<br/>搞录：<br/>问题：<br/>有没有办法在php中实现多线程呢？<br/>假设你正在写一个基于多台服务器的php应用，理想的情况时同时向多台服务器发送请求，而不是一台接一台。<br/>可以实现吗？<br/>回答：<br/>当有人想要实现并发功能时，他们通常会想到用fork或者spawn threads，但是当他们发现php不支持多线程的时候，大概会转换思路去用一些不够好的语言，比如perl。<br/>其实的是大多数情况下，你大可不必使用fork或者线程，并且你会得到比用fork或thread更好的性能。<br/>。。。<br/><br/>PHP5的先进之处在于，你可以用stream_select()处理几乎所有的stream-例如你可以通过include STDIN用它接收键盘输入并保存进数组，你还可以接收通过proc_open()打开的管道中的数据。<br/><br/>日常生活中：<br/>如对多个URL进行异步访问，那个curl_multi一族函数的函数是循环，而用这个就是真正调用类似Linux下的select函数：<br/>实践安装步骤如下：<br/>wget http://pecl.php.net/get/libevent-0.0.4.tgz<br/>checking for libevent support... yes, shared<br/>checking for libevent headers in default path... not found<br/>configure: error: Cannot find libevent headers<br/> root@192.168.1.108:~/software/libevent-0.0.4# yum -y install libevent-devel&nbsp;&nbsp; libevent<br/>不安libevent-devel会在具体安php的libevent扩展时出现找不到.h文件，用指定路径也成也就是下面的：<br/>最好还是安上吧，但要是版本低于1.4还是指定的好，可能会出现问题，这样：<br/>在安php的libevent扩展时加上 -with-libevent=/usr/local/webserver/libevent/： <br/>./configure&nbsp;&nbsp;-with-libevent=/usr/local/webserver/libevent/<br/>---<br/>原因是如下的包没有安装<br/>libevent-devel<br/>把此包安装上去就好了<br/>yum -y install libevent-devel<br/><br/>root@116.255.139.240:~/software# rpm -qa&#124;grep libevent<br/>libevent-1.4.13-1<br/>root@116.255.139.240:~/software# rpm -ql libevent-1.4.13-1<br/>/usr/lib/libevent-1.4.so.2<br/>/usr/lib/libevent-1.4.so.2.1.3<br/>/usr/lib/libevent_core-1.4.so.2<br/>/usr/lib/libevent_core-1.4.so.2.1.3<br/>/usr/lib/libevent_extra-1.4.so.2<br/>/usr/lib/libevent_extra-1.4.so.2.1.3<br/>/usr/share/doc/libevent-1.4.13<br/>/usr/share/doc/libevent-1.4.13/README<br/><br/>libevent的官网：http://libevent.org/<br/> wget https://github.com/downloads/libevent/libevent/libevent-2.0.16-stable.tar.gz<br/><br/>yum -y install libevent-devel&nbsp;&nbsp;主要是防止编译PHP扩展Configure时出现找不到.h文件，有了它就不用指明：-with-libevent=/usr/local/webserver/libevent/<br/>./configure prefix=/usr/local/webserver/libevent/<br/><br/>扩展安装：http://pecl.php.net/package/libevent<br/>wget http://pecl.php.net/get/libevent-0.0.4.tgz<br/>/usr/local/webserver/php/bin/phpize <br/>./configure&nbsp;&nbsp;-with-libevent=/usr/local/webserver/libevent/<br/>自己安或者yum，注意：yum安可能会出现问题:由於 PHP libevent 需要搭配C 的 libevent 1.4 以上版本 , 所以並非每個 Linux 套件都有 , 例如我的 CentOS 的 libevent 版本就比較舊 , 因此要自行編譯 , 以下就說明 CentOS 5.4 下成功編譯 PHP libevent 的步驟,PHP Warning:&nbsp;&nbsp;stream_select(): supplied argument is not a valid stream resource .<br/>root@192.168.1.108:~/software/libevent-0.0.4# ./configure&nbsp;&nbsp;-with-libevent=/usr/local/webserver/libevent/<br/> root@192.168.1.108:~/software/libevent-0.0.4# make;make install<br/>......<br/>........<br/> Build complete.<br/>Don&#039;t forget to run &#039;make test&#039;.<br/>Installing shared extensions:&nbsp;&nbsp;&nbsp;&nbsp; /usr/local/webserver/php/lib/php/extensions/no-debug-non-zts-20090626/<br/><br/>安装完毕，如下：<br/>/usr/local/webserver/php/lib/php/extensions/no-debug-non-zts-20090626/libevent.so<br/>DownLoad 测试源码，来自网上：<br/><a href="attachment.php?fid=235">点击这里下载文件</a><br/><br/>代码示例，来自网上,注释部分代码，测试读部分是ok的，如下：<br/><textarea name="code" class="html" rows="15" cols="100">
&lt;?php
$url = &quot;www.baidu.com&quot;;
if(array_key_exists(&#039;url&#039;,$_GET))&#123;
&nbsp;&nbsp;$url = $_GET[&#039;url&#039;];
&#125;
$hosts = array(&quot;www.baidu.com&quot;, &quot;www.google.com.hk&quot;);
#$hosts = array($url);
$timeout = 5;
$status = array();
$retdata = array();
$sockets = array();
$e = array();
/* Initiate connections to all the hosts simultaneously */
foreach ($hosts as $id =&gt; $host) &#123;
&nbsp;&nbsp;$errno = 0;
&nbsp;&nbsp;$errstr = &quot;&quot;;
&nbsp;&nbsp;$s = stream_socket_client(&quot;$host:80&quot;, $errno, $errstr, $timeout,STREAM_CLIENT_ASYNC_CONNECT&#124;STREAM_CLIENT_CONNECT);
&nbsp;&nbsp;if ($s) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;$sockets[$id] = $s;
&nbsp;&nbsp;&nbsp;&nbsp;$status[$id] = &quot;in progress&quot;;
&nbsp;&nbsp;&#125; else &#123;
&nbsp;&nbsp;&nbsp;&nbsp;$status[$id] = &quot;failed, $errno $errstr&quot;;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;$retdata[$id] = &#039;&#039;;
&#125;
/* Now, wait for the results to come back in */
while (count($sockets)) &#123;
&nbsp;&nbsp;echo &quot;Select function Judges read or write has&nbsp;&nbsp;status change&#92;n&quot;;
&nbsp;&nbsp;$read = $write = $sockets;
&nbsp;&nbsp;/* This is the magic function - explained below */
&nbsp;&nbsp;$n = stream_select($read, $write, $e, $timeout);
&nbsp;&nbsp;if ($n &gt; 0) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;/* readable sockets either have data for us, or are failed connection attempts */
&nbsp;&nbsp;&nbsp;&nbsp;foreach ($read as $r) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$id = array_search($r, $sockets);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$data = fread($r, 8192);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (strlen($data) == 0) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($status[$id] == &quot;in progress&quot;) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$status[$id] = &quot;failed to connect&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fclose($r);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset($sockets[$id]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125; else &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$retdata[$id] .= $data;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;/* writeable sockets can accept an HTTP request */
&nbsp;&nbsp;&nbsp;&nbsp;/*
&nbsp;&nbsp;&nbsp;&nbsp;foreach ($write as $w) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(!is_resource($w))continue;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$id = array_search($w, $sockets);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fwrite($w, &quot;GET / HTTP/1.0&#92;r&#92;nHost: &quot;.$hosts[$id].&quot;&#92;r&#92;n&#92;r&#92;n&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$status[$id] = &quot;waiting for response&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;*/
&nbsp;&nbsp;&#125; else &#123;
&nbsp;&nbsp;&nbsp;&nbsp;/* timed out waiting; assume that all hosts associated
&nbsp;&nbsp;&nbsp;&nbsp; * with $sockets are faulty */
&nbsp;&nbsp;&nbsp;&nbsp;foreach ($sockets as $id =&gt; $s) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$status[$id] = &quot;timed out &quot; . $status[$id];
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&#125;
&#125;
/*
foreach ($hosts as $id =&gt; $host) &#123;
#echo &quot;Host: $host&#92;n&quot;;
#echo &quot;Status: &quot; . $status[$id] . &quot;&#92;n&quot;;
#echo &quot;Retdata: &quot; . $retdata[$id] . &quot;&#92;n&quot;;
&nbsp;&nbsp;$strs = explode(&quot;&#92;r&#92;n&#92;r&#92;n&quot;,$retdata[$id],2);
&nbsp;&nbsp;echo isset($strs[1])?$strs[1]:$retdata[$id];
&#125;
function debug($i)&#123;
&nbsp;&nbsp;var_dump($i);
&nbsp;&nbsp;var_dump(gettype($i));
&nbsp;&nbsp;var_dump(is_resource($i));
&#125;
*/
?&gt;

</textarea><br/><br/><br/><br/><br/><br/>网上其他的步骤，主要是注意不有yum默认的安装方法【由於 PHP libevent 需要搭配C 的 libevent 1.4 以上版本 , 所以並非每個 Linux 套件都有 , 例如我的 CentOS 的 libevent 版本就比較舊 , 因此要自行編譯 , 以下就說明 CentOS 5.4 下成功編譯 PHP libevent 的步驟】：<br/><br/>1. 編譯 libevent<br/><br/>解開 libevent source code , 進入 source code 目錄<br/><br/>執行 ./configure –prefix=/usr/local<br/><br/>執行 make<br/><br/>執行 make install<br/><br/>2. 編譯 PHP libevent<br/><br/>解開 PHP libevent source code , 進入 source code 目錄<br/><br/>執行 phpize<br/><br/>執行 ./configure –with-libevent=/usr/local<br/><br/>執行 make<br/><br/>執行 make install<br/><br/>這樣會把 libevent.so 安裝到 /usr/lib/php/modoules 或 /usr/lib64/php/modules , 看 os 是 32bit 或 64bit<br/><br/>同时呢，也可以参考下这个URL：http://www.ooso.net/archives/607<br/><br/>附录，关于curl_multi一族函数的问题：<br/><br/>相信许多人对php手册中语焉不详的curl_multi一族的函数头疼不已，它们文档少，给的例子 更是简单的让你无从借鉴，我也曾经找了许多网页，都没见一个完整的应用例子。<br/>curl_multi_add_handle<br/>curl_multi_close<br/>curl_multi_exec<br/>curl_multi_getcontent<br/>curl_multi_info_read<br/>curl_multi_init<br/>curl_multi_remove_handle<br/>curl_multi_select<br/>一般来说，想到要用这些函数时，目的显然应该是要同时请求多个url，而不是一个一个依次请求，否则不如自己循环去调curl_exec好了。<br/>步骤总结如下：<br/>第一步：调用curl_multi_init<br/>第二步：循环调用curl_multi_add_handle<br/>这一步需要注意的是，curl_multi_add_handle的第二个参数是由curl_init而来的子handle。<br/>第三步：持续调用curl_multi_exec<br/>第四步：根据需要循环调用curl_multi_getcontent获取结果<br/>第五步：调用curl_multi_remove_handle，并为每个字handle调用curl_close<br/>第六步：调用curl_multi_close<br/>这里有一个网上找的简单例子，其作者称为dirty的例子，（稍后我会说明为何dirty）：<br/><textarea name="code" class="html" rows="15" cols="100">
/*
Here’s a quick and dirty example for curl-multi from PHP, tested on PHP 5.0.0RC1 CLI / FreeBSD 5.2.1
*/
&lt;?php
$connomains = array(
&quot;http://www.cnn.com/&quot;,
&quot;http://www.canada.com/&quot;,
&quot;http://www.yahoo.com/&quot;
);
　　
?$mh = curl_multi_init();
　　
foreach (?$connomains as ?$i =&gt; ?$url) &#123;
　　 ?$conn[?$i]=curl_init(?$url);
　　　curl_setopt(?$conn[?$i],CURLOPT_RETURNTRANSFER,1);
　　　curl_multi_add_handle (?$mh,?$conn[?$i]);
&#125;
　　
do &#123; ?$n=curl_multi_exec(?$mh,?$active); &#125; while (?$active);
　　
foreach (?$connomains as ?$i =&gt; ?$url) &#123;
　　　?$res[?$i]=curl_multi_getcontent(?$conn[?$i]);
　　　curl_close(?$conn[?$i]);
&#125;
　　
print_r(?$res);
?&gt;
</textarea><br/>整个使用过程差不多就是这样，但是，这个简单代码有个致命弱点，就是在do循环的那段，在整个url请求期间是个死循环，它会轻易导致CPU占用100%。<br/>现在我们来改进它，这里要用到一个几乎没有任何文档的函数curl_multi_select了，虽然C的curl库对select有说明，但是，php里的接口和用法确与C中有不同。<br/>把上面do的那段改成下面这样：<br/><textarea name="code" class="html" rows="15" cols="100">
do &#123;
　　　　?$mrc = curl_multi_exec(?$mh,?$active);
&#125; while (?$mrc == CURLM_CALL_MULTI_PERFORM);
while (?$active and ?$mrc == CURLM_OK) &#123;　　　if (curl_multi_select(?$mh) != -1) &#123;
　　　　　　　　do &#123;
　　　　　　　　　　　　?$mrc = curl_multi_exec(?$mh, ?$active);
　　　　　　　　&#125; while (?$mrc == CURLM_CALL_MULTI_PERFORM);
　　　　&#125;
&#125;
</textarea><br/>因为?$active要等全部url数据接受完毕才变成false，所以这里用到了<br/>curl_multi_exec的返回值判断是否还有数据，当有数据的时候就不停调用curl_multi_exec，暂时没有数据就进入select阶段，新数据一来就可以被唤醒继续执行。这里的好处就是CPU的无谓消耗没有了。<br/>另外：还有一些细节的地方可能有时候要遇到：<br/>控制每一个请求的超时时间，在curl_multi_add_handle之前通过curl_setopt去做：<br/><textarea name="code" class="html" rows="15" cols="100">
curl_setopt(?$ch, CURLOPT_TIMEOUT, ?$timeout);
</textarea><br/>判断是否超时了或者其他错误，在curl_multi_getcontent之前用：curl_error(?$conn[?$i]);<br/><br/><br/>相关参考：<br/>http://www.iteye.com/news/21255-swoole-php-framework<br/>http://code.google.com/p/swoole/<br/>http://blog.163.com/huv520@126/blog/static/2776523920119149283594/<br/>http://matyhtf.iteye.com/blog/844311<br/><br/><br/>实践代码如下，运行成功：<br/><textarea name="code" class="html" rows="15" cols="100">
&lt;?php
echo &quot;Program starts at &quot;. date(&#039;h:i:s&#039;) . &quot;.&#92;n&quot;;
$timeout=10;
$streams=array();
$handles=array();
/* First launch a program with a delay of three seconds, then
one which returns after only one second. */
$delay=3;
for ($id=0; $id &lt;= 1; $id++) &#123;
$error_log=&quot;/tmp/error&quot; . $id . &quot;.txt&quot;;
$descriptorspec=array(
0 =&gt; array(&quot;pipe&quot;, &quot;r&quot;),
1 =&gt; array(&quot;pipe&quot;, &quot;w&quot;),
2 =&gt; array(&quot;file&quot;, $error_log, &quot;w&quot;)
);
$cmd=&#039;sleep &#039; . $delay . &#039;; echo &quot;Finished with delay of &#039; . $delay . &#039;&quot;.&#039;;
$handles[$id]=proc_open($cmd, $descriptorspec, $pipes);
$streams[$id]=$pipes[1];
$all_pipes[$id]=$pipes;
$delay -= 2;
&#125;
while (count($streams)) &#123;
$read=$streams;
stream_select($read, $w=null, $e=null, $timeout);
foreach ($read as $r) &#123;
$id=array_search($r, $streams);
echo stream_get_contents($all_pipes[$id][1]);
if (feof($r)) &#123;
fclose($all_pipes[$id][0]);
fclose($all_pipes[$id][1]);
$return_value=proc_close($handles[$id]);
unset($streams[$id]);
&#125;
&#125;
&#125;
?&gt;
</textarea><br/>执行如下：<br/>root@116.255.139.240:/home/admin/php/stream_select# php stream_select.php<br/>Program starts at 02:30:27.<br/>Finished with delay of 1.<br/>Finished with delay of 3.<br/>这里的关键在于 PHP 启动了两个独立子进程，取回待完成的第一个进程的输出，然后取回第二个进程的输出，即使后者启动得较早。如果主机是多处理器计算机，并且操作系统已正确配置，则操作系统本身负责将各个子程序分配给不同的处理器。这是在多处理器主机中良好应用 PHP 的一种方法。<br/><br/><br/>时间如下，特别注意是这样的如果是PHp串口实现fd的话，因为只有这个常规的fd才能用stream_select监控，而PHP的串口扩展是不行的，我实践了好几次才发现这个问题，<br/>dio.raw://[device]<br/>for raw streams and<br/>dio.serial://[device<br/>for serials streams. <br/>这两种stream有什么区别啊？这点我不太明白，反正用raw就能读取到，而用serial就不行，<br/>用serial不行，而用raw就Ok了，也就满足了偶的需求，呵呵。<br/>参考的扩展和实践Ok的代码都来自：http://www.cyberspice.org.uk/blog/2010/02/15/serial-io-in-php-using-the-dio-extension/<br/><br/>Ok的读取代码如下：<br/>&lt;?php <br/>&nbsp;&nbsp;Error_reporting(E_ALL);<br/>&nbsp;&nbsp;// Create a stream context that configures the serial port<br/>&nbsp;&nbsp;// And enables canonical input.<br/>&nbsp;&nbsp;$c = stream_context_create(array(&#039;dio&#039; =&gt; <br/>&nbsp;&nbsp;&nbsp;&nbsp;array(&#039;data_rate&#039; =&gt; 9600, <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;data_bits&#039; =&gt; 8, <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;stop_bits&#039; =&gt; 1, <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;parity&#039; =&gt; 0, <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;is_canonical&#039; =&gt; 1)));<br/> <br/>&nbsp;&nbsp;// Are we POSIX or Windows?&nbsp;&nbsp;POSIX platforms do not have a<br/>&nbsp;&nbsp;// Standard port naming scheme so it could be /dev/ttyUSB0<br/>&nbsp;&nbsp;// or some long /dev/tty.serial_port_name_thingy on OSX.<br/>&nbsp;&nbsp;$filename = &quot;dio.raw:///dev/ttyUSB0&quot;;<br/> <br/>&nbsp;&nbsp;// Open the stream for read only and use it.<br/>&nbsp;&nbsp;$f = fopen($filename, &quot;r+&quot;, false, $c);<br/>&nbsp;&nbsp;stream_set_blocking($f, 0);<br/>&nbsp;&nbsp;if ($f) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;echo &quot;Reading from port...&#92;n&quot;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;while(1)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//$data = fgets($f);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$data =&nbsp;&nbsp;fread($f,10);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($data) <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo $data.&quot;&#92;n&quot;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&#125;<br/>?&gt;<br/><br/>参考其他网上的实例代码如下，代码来自，http://plugins.svn.wordpress.org/wp-tsina/trunk/wp-tsina.curl.cls.php：<br/><br/><textarea name="code" class="html" rows="15" cols="100">
&lt;?php
/**
 * curl发送请求
 */
define(&#039;CURLW_ERR_OK&#039;,0);
define(&#039;CURLW_ERR_NORMAL&#039;,-1);
define(&#039;CURLW_ERR_TIMEOUT&#039;,-2);
define(&#039;CURLW_ERR_TIMEOUT_RW&#039;,-3);
define(&#039;CURLW_ERR_CONNECT_REFUSED&#039;,-4);

class CurlWrapper
&#123;
&nbsp;&nbsp;//连接超时
&nbsp;&nbsp;var $_tm_con = 5;
&nbsp;&nbsp;//读写超时 
&nbsp;&nbsp;var $_tm_rw = 5;
&nbsp;&nbsp;//stream_select超时(ms)
&nbsp;&nbsp;var $_tm_select = 2000000;
&nbsp;&nbsp;//多进程
&nbsp;&nbsp;var $_multiple = 0;
&nbsp;&nbsp;//请求数组
&nbsp;&nbsp;var $_req_arr = array();
&nbsp;&nbsp;//回应数组
&nbsp;&nbsp;var $_res_arr = array();
&nbsp;&nbsp;//是否输出调试信息
&nbsp;&nbsp;var $_if_debug = 0;
&nbsp;&nbsp;//调试信息
&nbsp;&nbsp;var $_debug = array();
&nbsp;&nbsp;//错误信息
&nbsp;&nbsp;var $_error = &#039;&#039;;
&nbsp;&nbsp;//是否安装了curl包
&nbsp;&nbsp;var $_curl_package = 1;
&nbsp;&nbsp;
&nbsp;&nbsp;function CurlWrapper()
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;checkCurlPackage();
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;
&nbsp;&nbsp;/**
&nbsp;&nbsp; * 调试函数
&nbsp;&nbsp; */
&nbsp;&nbsp;function debug($info,$newline=&quot;&#92;n&quot;)
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;echo $info.$newline;
&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_debug[] = $info;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;
&nbsp;&nbsp;/**
&nbsp;&nbsp; * 监测是否安装了curl包
&nbsp;&nbsp; */
&nbsp;&nbsp;function checkCurlPackage()
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;if( !function_exists(&#039;curl_init&#039;) )
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_curl_package = 0;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;
&nbsp;&nbsp;/**
&nbsp;&nbsp; * 设置是否采用并发形式
&nbsp;&nbsp; */
&nbsp;&nbsp;function setMultiple($status=0)
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_multiple = $status;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;
&nbsp;&nbsp;/**
&nbsp;&nbsp; * 设置是否输出调试信息
&nbsp;&nbsp; */
&nbsp;&nbsp;function setDebug($status=0)
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_if_debug = $status;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;
&nbsp;&nbsp;/**
&nbsp;&nbsp; * 设置stream_select超时(ms)
&nbsp;&nbsp; */
&nbsp;&nbsp;function setSelectTimeout($time)
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_tm_select = $time;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;
&nbsp;&nbsp;/**
&nbsp;&nbsp; * 打印debug信息
&nbsp;&nbsp; */
&nbsp;&nbsp;function &amp;getDebug()
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;return $this-&gt;_debug;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;
&nbsp;&nbsp;/**
&nbsp;&nbsp; * 获取返回结果
&nbsp;&nbsp; */
&nbsp;&nbsp;function &amp;getResult()
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;return $this-&gt;_res_arr;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;
&nbsp;&nbsp;/**
&nbsp;&nbsp; * 获取指定key的结果
&nbsp;&nbsp; */
&nbsp;&nbsp;function &amp;getResultByKey($key)
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;return $this-&gt;_res_arr[$key];
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;
&nbsp;&nbsp;/**
&nbsp;&nbsp; * 获取结果状态
&nbsp;&nbsp; */
&nbsp;&nbsp;function getResultStatus(&amp;$params)
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;if( $params[&#039;errno&#039;] != CURLW_ERR_OK )
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$params[&#039;error&#039;] = &#039;curl_error=&#039;.$params[&#039;error&#039;].&#039;,curl_errno=&#039;.$params[&#039;errno&#039;].&#039;,curl_code=&#039;.$params[&#039;code&#039;];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;else if( $params[&#039;errno&#039;] == CURLW_ERR_OK &amp;&amp; $params[&#039;code&#039;] != &#039;200&#039; )
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$params[&#039;error&#039;] = &#039;curl_error=&#039;.$params[&#039;error&#039;].&#039;,curl_errno=&#039;.$params[&#039;errno&#039;].&#039;,curl_code=&#039;.$params[&#039;code&#039;];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;return true;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;
&nbsp;&nbsp;/**
&nbsp;&nbsp; * 添加一个请求
&nbsp;&nbsp; */
&nbsp;&nbsp;function addRequest($params=null)
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;//url形式默认为get方式请求
&nbsp;&nbsp;&nbsp;&nbsp;if( $params[&#039;url&#039;] ) 
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$url_arr = parse_url($params[&#039;url&#039;]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$params[&#039;method&#039;] = $params[&#039;method&#039;] ? $params[&#039;method&#039;] : &#039;get&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$params[&#039;host&#039;] = $url_arr[&#039;host&#039;];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$params[&#039;uri&#039;] = $url_arr[&#039;path&#039;].&#039;?&#039;.$url_arr[&#039;query&#039;];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$params[&#039;port&#039;] = $url_arr[&#039;port&#039;];
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;//host
&nbsp;&nbsp;&nbsp;&nbsp;if( !$params[&#039;host&#039;] )
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;debug(&#039;[&#039;.__FUNCTION__.&#039;:&#039;.__LINE__.&#039;]host为空&#039;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;//uri
&nbsp;&nbsp;&nbsp;&nbsp;if( !$params[&#039;uri&#039;] )
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;debug(&#039;[&#039;.__FUNCTION__.&#039;:&#039;.__LINE__.&#039;]uri为空&#039;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;//port
&nbsp;&nbsp;&nbsp;&nbsp;if( !$params[&#039;port&#039;] )
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$params[&#039;port&#039;] = 80;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;//proxy host
&nbsp;&nbsp;&nbsp;&nbsp;if( $params[&#039;proxy_host&#039;] )
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$params[&#039;uri&#039;] = &#039;http://&#039;.$params[&#039;host&#039;].&#039;:&#039;.$params[&#039;port&#039;].&#039;/&#039;.$params[&#039;uri&#039;];
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;//proxy port
&nbsp;&nbsp;&nbsp;&nbsp;if( !$params[&#039;proxy_port&#039;] )
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$params[&#039;proxy_port&#039;] = 80;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;//method
&nbsp;&nbsp;&nbsp;&nbsp;$method = strtolower($params[&#039;method&#039;]);
&nbsp;&nbsp;&nbsp;&nbsp;if( $method != &#039;get&#039; &amp;&amp; $method != &#039;post&#039; &amp;&amp; $method != &#039;purge&#039; &amp;&amp; $method != &#039;header&#039; )
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$params[&#039;method&#039;] = &#039;get&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;//请求内容
&nbsp;&nbsp;&nbsp;&nbsp;$content = trim($params[&#039;content&#039;]);
&nbsp;&nbsp;&nbsp;&nbsp;if( $method == &#039;post&#039; &amp;&amp; $content == &#039;&#039; )
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;debug(&#039;[&#039;.__FUNCTION__.&#039;:&#039;.__LINE__.&#039;]请求内容为空&#039;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;//connection timeout
&nbsp;&nbsp;&nbsp;&nbsp;if( !$params[&#039;timeout&#039;] )
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$params[&#039;timeout&#039;] = $this-&gt;_tm_con;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;//read,write timeout
&nbsp;&nbsp;&nbsp;&nbsp;if( !$params[&#039;timeout_rw&#039;] )
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$params[&#039;timeout_rw&#039;] = $this-&gt;_tm_rw;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;if( $params[&#039;key&#039;] ) $this-&gt;_req_arr[$params[&#039;key&#039;]] = $params;
&nbsp;&nbsp;&nbsp;&nbsp;else $this-&gt;_req_arr[] = $params;
&nbsp;&nbsp;&nbsp;&nbsp;if( $this-&gt;_if_debug ) print_r($this-&gt;_req_arr);
&nbsp;&nbsp;&nbsp;&nbsp;return true;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;
&nbsp;&nbsp;function send()
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;if( $this-&gt;_multiple == 0 )//非并发请求
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( !$this-&gt;_curl_package )&nbsp;&nbsp;$this-&gt;_sendRequest();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else $this-&gt;_sendRequestByCURL();
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;else if( $this-&gt;_multiple == 1 )//并发请求
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_sendMultiRequest();
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;
&nbsp;&nbsp;/**
&nbsp;&nbsp; * 发送请求 -&gt; 连接超时判断 -&gt; 读写超时判断
&nbsp;&nbsp; */
&nbsp;&nbsp;function _sendRequest()
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;foreach( $this-&gt;_req_arr as $req_key=&gt;$req )
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//初始化数据
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$errno = CURLW_ERR_OK;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$error = &quot;&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ret_arr = array(&#039;errno&#039;=&gt;0,&#039;error&#039;=&gt;&#039;&#039;,&#039;data&#039;=&gt;&#039;&#039;,&#039;code&#039;=&gt;&#039;&#039;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//调试
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( $this-&gt;_if_debug )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;debug($fp);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$debug_msg = &#039;&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach( $req as $req_key_debug=&gt;$req_val_debug ) $debug_msg.= $req_key_debug.&#039;=&#039;.$req_val_debug.&quot;,&#92;n&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;debug($debug_msg);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//创建句柄
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//if( $req[&#039;proxy_host&#039;] ) $fp = @fsockopen($req[&#039;proxy_host&#039;],$req[&#039;proxy_port&#039;],$errno,$error,$req[&#039;timeout&#039;]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//else $fp = @fsockopen($req[&#039;host&#039;],$req[&#039;port&#039;],$errno,$error,$req[&#039;timeout&#039;]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( $req[&#039;proxy_host&#039;] )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$req[&#039;host&#039;] = $req[&#039;proxy_host&#039;];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$req[&#039;port&#039;] = $req[&#039;proxy_port&#039;];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$fp = @fsockopen($req[&#039;host&#039;],$req[&#039;port&#039;],$errno,$error,$req[&#039;timeout&#039;]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( !$fp )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( $this-&gt;_if_debug ) $this-&gt;debug(&#039;[&#039;.__FUNCTION__.&#039;:&#039;.__LINE__.&#039;]host=&#039;.$req[&#039;host&#039;].&#039;,error=&#039;.$error);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( $errno == 60 ) $ret_arr[&#039;errno&#039;] = CURLW_ERR_TIMEOUT;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else if( $errno == 61 ) $ret_arr[&#039;errno&#039;] = CURLW_ERR_CONNECT_REFUSED;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else $ret_arr[&#039;errno&#039;] = CURLW_ERR_NORMAL;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ret_arr[&#039;error&#039;] = &#039;[&#039;.$errno.&#039;]&#039;.$error;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ret_arr[&#039;data&#039;] = &#039;&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ret_arr[&#039;code&#039;] = &#039;&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_res_arr[$req_key] = $ret_arr;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;continue;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//发送请求
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$reqstr = &amp;$this-&gt;_getRequestStr($req);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( $this-&gt;_if_debug ) $this-&gt;debug(&#039;request=&#039;.$reqstr);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@fwrite($fp,$reqstr,strlen($reqstr));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//设置读取超时时间
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$tm_rw = isset($req[&#039;timeout_rw&#039;])?$req[&#039;timeout_rw&#039;]:$this-&gt;_tm_rw;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stream_set_timeout($fp,$tm_rw);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//获取返回内容
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( $retval=$this-&gt;_getResponseStr( array(&#039;fp&#039;=&gt;$fp,&#039;header&#039;=&gt;1) ) )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ret_arr[&#039;errno&#039;] = CURLW_ERR_OK;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ret_arr[&#039;error&#039;] = &#039;&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ret_arr[&#039;data&#039;] = trim(strstr($retval,&quot;&#92;r&#92;n&#92;r&#92;n&quot;));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ret_arr[&#039;code&#039;] = $this-&gt;_getHTTPCode($retval);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_res_arr[$req_key] = $ret_arr;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ret_arr[&#039;errno&#039;] = CURLW_ERR_TIMEOUT_RW;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ret_arr[&#039;error&#039;] = $this-&gt;_error;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ret_arr[&#039;data&#039;] = &#039;&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ret_arr[&#039;code&#039;] = &#039;&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_res_arr[$req_key] = $ret_arr;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fclose($fp);
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;
&nbsp;&nbsp;/**
&nbsp;&nbsp; * 使用curl发送请求
&nbsp;&nbsp; */
&nbsp;&nbsp;function _sendRequestByCURL()
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;foreach( $this-&gt;_req_arr as $req_key=&gt;$req )
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//初始化数据
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ret_arr = array(&#039;errno&#039;=&gt;CURLW_ERR_OK,&#039;error&#039;=&gt;&#039;&#039;,&#039;data&#039;=&gt;&#039;&#039;,&#039;code&#039;=&gt;&#039;&#039;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( !$req[&#039;url&#039;] ) $req[&#039;url&#039;] = &#039;http://&#039;.$req[&#039;host&#039;].&#039;:&#039;.$req[&#039;port&#039;].$req[&#039;uri&#039;];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( $this-&gt;_if_debug ) $this-&gt;debug(&#039;[&#039;.__FUNCTION__.&#039;:&#039;.__LINE__.&#039;]url=&#039;.$req[&#039;url&#039;]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//创建句柄
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$curl_handle = curl_init($req[&#039;url&#039;]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//设置选项
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( $this-&gt;_if_debug ) curl_setopt($curl_handle,CURLOPT_VERBOSE,1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;curl_setopt($curl_handle,CURLOPT_TIMEOUT,$req[&#039;timeout_rw&#039;]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;curl_setopt($curl_handle,CURLOPT_RETURNTRANSFER,1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;curl_setopt($curl_handle,CURLOPT_HEADER,1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( $req[&#039;method&#039;] == &#039;post&#039; )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;curl_setopt($curl_handle,CURLOPT_POST,1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;curl_setopt($curl_handle,CURLOPT_POSTFIELDS,$req[&#039;content&#039;]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;else if( $req[&#039;method&#039;] == &#039;header&#039; )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;curl_setopt($curl_handle, CURLOPT_NOBODY, 1); 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;curl_setopt($curl_handle, CURLOPT_HEADER, 1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( $req[&#039;proxy_host&#039;] ) curl_setopt($curl_handle,CURLOPT_PROXY,$req[&#039;proxy_host&#039;].&#039;:&#039;.$req[&#039;proxy_port&#039;]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//发送请求,获取返回内容
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$curl_rst = curl_exec($curl_handle);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( $this-&gt;_if_debug ) $this-&gt;debug(&#039;[_sendRequestByCURL]&#039;.$curl_rst);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( !$curl_rst )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( curl_errno($curl_handle) == CURLE_OPERATION_TIMEOUTED )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ret_arr[&#039;errno&#039;] = CURLW_ERR_TIMEOUT_RW;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ret_arr[&#039;error&#039;] = curl_error($curl_handle);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ret_arr[&#039;data&#039;] = &#039;&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ret_arr[&#039;code&#039;] = &#039;&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_res_arr[$req_key] = $ret_arr;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ret_arr[&#039;errno&#039;] = CURLW_ERR_OK;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ret_arr[&#039;error&#039;] = &#039;&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( $req[&#039;method&#039;] == &#039;header&#039; )&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ret_arr[&#039;data&#039;] = curl_getinfo( $curl_handle );
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;else &#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ret_arr[&#039;data&#039;] = trim(strstr($curl_rst,&quot;&#92;r&#92;n&#92;r&#92;n&quot;));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ret_arr[&#039;code&#039;] = $this-&gt;_getHTTPCode($curl_rst);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_res_arr[$req_key] = $ret_arr;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//关闭
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;curl_close($curl_handle);
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;
&nbsp;&nbsp;/**
&nbsp;&nbsp; * 发送并发请求
&nbsp;&nbsp; * 连接超时有效
&nbsp;&nbsp; * 读写超时无效
&nbsp;&nbsp; * stream_select超时用来控制程序执行时间
&nbsp;&nbsp; */
&nbsp;&nbsp;function _sendMultiRequest()
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;$fp_r = array();
&nbsp;&nbsp;&nbsp;&nbsp;foreach( $this-&gt;_req_arr as $req_key=&gt;$req )
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$errno = 0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$error = &quot;&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//创建句柄
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( $req[&#039;proxy_host&#039;] ) $fp = @fsockopen($req[&#039;proxy_host&#039;],$req[&#039;proxy_port&#039;],$errno,$error,$req[&#039;timeout&#039;]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else $fp = @fsockopen($req[&#039;host&#039;],$req[&#039;port&#039;],$errno,$error,$req[&#039;timeout&#039;]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( !$fp )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( $this-&gt;_if_debug ) $this-&gt;debug(&#039;[&#039;.__FUNCTION__.&#039;:&#039;.__LINE__.&#039;]host=&#039;.$req[&#039;host&#039;].&#039;,error=&#039;.$error);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;continue;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$fp_r[] = $fp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( $this-&gt;_if_debug )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$debug_msg = $fp.&#039;,host=&#039;.$req[&#039;host&#039;].&#039;,uri=&#039;.$req[&#039;uri&#039;].&#039;,port=&#039;.$req[&#039;port&#039;].&#039;,timeout=&#039;.$req[&#039;timeout&#039;];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo $debug_msg.&quot;&#92;n&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_debug[] = $debug_msg;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//设置为非阻塞模式
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stream_set_blocking($fp,0);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//发送请求
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$reqstr = &amp;$this-&gt;_getRequestStr($req);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@fwrite($fp,$reqstr,strlen($reqstr));
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;$stime = microtime(true);
&nbsp;&nbsp;&nbsp;&nbsp;while( 1 )
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//利用select原理,获取有效fp
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$fp_r_select = $fp_r;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ret_select = stream_select($fp_r_select,$fp_w_select=null,$fp_e_select=null,0,$this-&gt;_selectTimeout($this-&gt;_tm_select,$stime));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( $ret_select === false &#124;&#124; $ret_select == 0 )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( $ret_select === false ) $this-&gt;_debug[] = &#039;stream_select错误&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else if( $ret_select == 0 ) $this-&gt;_debug[] = &#039;stream_select超时&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//if( $this-&gt;_if_debug ) echo &#039;***fp_r_select:&#039;.implode(&#039;,&#039;,$fp_r_select).&quot;&#92;n&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach( $fp_r_select as $fp )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( !is_resource($fp) )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( $this-&gt;_if_debug ) echo $fp.&#039;,error!&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;continue;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$tmp = $this-&gt;_getResponseStr( array(&#039;fp&#039;=&gt;$fp,&#039;header&#039;=&gt;0) );
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//清除不用的fp对象
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach( $fp_r as $fp_r_key=&gt;$fp_r_val )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( $fp_r_val == $fp )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_res_arr[$fp_r_key] = $tmp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//if( $this-&gt;_if_debug ) echo $fp_r[$fp_r_key].&quot;,被关闭&#92;n&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( feof($fp_r_val) ) fclose($fp_r[$fp_r_key]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unset($fp_r[$fp_r_key]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//退出
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( count($fp_r)==0 )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;
&nbsp;&nbsp;/**
&nbsp;&nbsp; * 使用curl发送并发请求
&nbsp;&nbsp; */
&nbsp;&nbsp;function _sendMultiRequestByCurl()
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;//在子类中实现
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;
&nbsp;&nbsp;/**
&nbsp;&nbsp; * 获取返回字符串
&nbsp;&nbsp; */
&nbsp;&nbsp;function _getResponseStr($params=null)
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;if( !$params[&#039;fp&#039;] )
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( $this-&gt;_if_debug ) $this-&gt;debug(&#039;[&#039;.__FUNCTION__.&#039;:&#039;.__LINE__.&#039;]fp无效&#039;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;$fp = $params[&#039;fp&#039;];
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;$tmp = &quot;&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;while( !feof($fp) )
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$tmp.= @fread($fp,1024);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$info = stream_get_meta_data($fp);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( $info[&#039;timed_out&#039;] )//超时
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( $this-&gt;_if_debug ) $this-&gt;debug(&#039;[&#039;.__FUNCTION__.&#039;:&#039;.__LINE__.&#039;]&#039;.$fp.&#039;,获取数据超时&#039;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;_error = &#039;获取数据超时&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;//if( $this-&gt;_if_debug ) $this-&gt;debug(&#039;[_getResponseStr]服务器返回结果=&#039;.$tmp);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;//是否保留头信息
&nbsp;&nbsp;&nbsp;&nbsp;$header = isset($params[&#039;header&#039;])?$params[&#039;header&#039;]:0;
&nbsp;&nbsp;&nbsp;&nbsp;if( !$header )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$tmp = strstr($tmp,&quot;&#92;r&#92;n&#92;r&#92;n&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;$str = trim($tmp);

&nbsp;&nbsp;&nbsp;&nbsp;return $str;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;
&nbsp;&nbsp;/**
&nbsp;&nbsp; * 返回发送请求字符串
&nbsp;&nbsp; */
&nbsp;&nbsp;function &amp;_getRequestStr($params=null)
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;switch($params[&#039;method&#039;])
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case &#039;post&#039;:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$reqstr = &quot;POST &quot;.$params[&#039;uri&#039;].&quot; HTTP/1.0&#92;r&#92;n&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$reqstr.= &quot;Host: &quot;.$params[&#039;host&#039;].&quot;&#92;r&#92;n&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$reqstr.= &quot;Content-type: application/x-www-form-urlencoded&#92;r&#92;n&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$reqstr.= &quot;Content-length: &quot;.strlen($params[&#039;content&#039;]).&quot;&#92;r&#92;n&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$reqstr.= &quot;Connection: Close&#92;r&#92;n&#92;r&#92;n&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$reqstr.= $params[&#039;content&#039;];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case &#039;purge&#039;:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$reqstr = &quot;PURGE &quot;.$params[&#039;uri&#039;].&quot; HTTP/1.1&#92;n&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$reqstr.= &quot;Host: &quot;.$params[&#039;host&#039;].&quot;&#92;n&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$reqstr.= &quot;Connection: Close&#92;n&#92;n&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case &#039;get&#039;:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case &#039;header&#039;:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$reqstr = &quot;GET &quot;.$params[&#039;uri&#039;].&quot; HTTP/1.0&#92;r&#92;n&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$reqstr.= &quot;Host: &quot;.$params[&#039;host&#039;].&quot;&#92;r&#92;n&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$reqstr.= &quot;Connection: Close&#92;r&#92;n&#92;r&#92;n&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;return $reqstr;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;
&nbsp;&nbsp;/**
&nbsp;&nbsp; * 计算stream_select需要超时的时间
&nbsp;&nbsp; */
&nbsp;&nbsp;function _selectTimeout($mtime,$stime)
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;$time = $mtime - ((microtime(true) - $stime) * 1000000);
&nbsp;&nbsp;&nbsp;&nbsp;if( $time &lt; 0 ) $time = 0;
&nbsp;&nbsp;&nbsp;&nbsp;$time = ceil($time);
&nbsp;&nbsp;&nbsp;&nbsp;//if( $this-&gt;_if_debug ) echo &#039;time=&#039;.$time.&quot;&#92;n&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;return $time;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;
&nbsp;&nbsp;/**
&nbsp;&nbsp; * 获取http code
&nbsp;&nbsp; */
&nbsp;&nbsp;function _getHTTPCode(&amp;$str)
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;$header_line1 = substr($str,0,strpos($str,&quot;&#92;n&quot;));
&nbsp;&nbsp;&nbsp;&nbsp;$header_line1 = trim($header_line1);
&nbsp;&nbsp;&nbsp;&nbsp;$arr = explode(&#039; &#039;,$header_line1);
&nbsp;&nbsp;&nbsp;&nbsp;return $arr[1];
&nbsp;&nbsp;&#125;
&#125;
?&gt;
</textarea><br/><br/><br/><br/>因blog搬家，最后的代码作为附件没有存下来，于是在此补充上：<br/><textarea name="code" class="php" rows="15" cols="100">
&lt;?php
Error_reporting(E_ALL);
$hosts = array(&quot;/dev/ttyUSB0&quot; ,&quot;/dev/ttyUSB1&quot; ,&quot;/dev/ttyUSB2&quot; ,&quot;/dev/ttyUSB3&quot; ,&quot;/dev/ttyUSB4&quot; ,&quot;/dev/ttyUSB5&quot; ,&quot;/dev/ttyUSB6&quot; ,&quot;/dev/ttyUSB7&quot;);

$timeout = 1;
$status = array ();
$sockets = array ();
$c = stream_context_create(array(&#039;dio&#039; =&gt; 
&nbsp;&nbsp;array(&#039;data_rate&#039; =&gt; 9600, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;data_bits&#039; =&gt; 8, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;stop_bits&#039; =&gt; 1, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;parity&#039; =&gt; 0, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;is_canonical&#039; =&gt; 1)));
foreach($hosts as $id =&gt;$host)
&#123;
&nbsp;&nbsp;if( file_exists($host) )
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;$s = fopen($host, &quot;r+&quot;, false, $c);
&nbsp;&nbsp;&nbsp;&nbsp;stream_set_blocking($s, true);
&nbsp;&nbsp;&nbsp;&nbsp;$data = fread($s,10);&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;$sockets[$id] = $s;
&nbsp;&nbsp;&nbsp;&nbsp;//$sockets[1] = $s;
&nbsp;&nbsp;&nbsp;&nbsp;$status[$id] = &quot;in progress&quot;;
&nbsp;&nbsp;&#125;
&#125;
while (count($sockets))
&#123;
&nbsp;&nbsp;$read = $sockets;
&nbsp;&nbsp;$write = null;
&nbsp;&nbsp;$n =&nbsp;&nbsp;stream_select($read,$write,$e=null,$timeout);
&nbsp;&nbsp;if ($n === false) 
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&#125; else if ($n === 0) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;/* timed out */
&nbsp;&nbsp;&nbsp;&nbsp;$data = &quot;&#92;nERROR:&quot;.&quot; Com-N &quot;.&quot;timed out&quot;;
&nbsp;&nbsp;&#125; else if ($n &gt; 0) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;foreach ($read as $r) 
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$id = array_search($r, $sockets);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//$data= (binary)fread($r, 10);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$data= fread($r, 10);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (strlen($data) == 0) 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;echo $data.&quot;&#92;n&quot;;
&#125;
?&gt;

</textarea><br/><br/><br/>单个程序读取Ok在raspberry硬件上：<br/><textarea name="code" class="php" rows="15" cols="100">
&lt;?php
$c = stream_context_create(array(&#039;dio&#039; =&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array(&#039;data_rate&#039; =&gt; 9600,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;data_bits&#039; =&gt; 8,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;stop_bits&#039; =&gt; 1,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;parity&#039; =&gt; 0,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;flow_control&#039; =&gt; 0,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;is_canonical&#039; =&gt; 1)));
// Are we POSIX or Windows?&nbsp;&nbsp;POSIX platforms do not have a
// Standard port naming scheme so it could be /dev/ttyUSB0
// or some long /dev/tty.serial_port_name_thingy on OSX.
if (PATH_SEPARATOR != &quot;;&quot;) &#123;
&nbsp;&nbsp;$filename = &quot;dio.serial:///dev/ttyUSB0&quot;;
&#125; else &#123;
&nbsp;&nbsp;$filename = &quot;dio.serial://dev/ttyUSB0&quot;;
&#125;
// Open the stream for read and write and use it.
$f = fopen($filename, &quot;r+&quot;, false, $c);
if ($f)
&#123;
&nbsp;&nbsp;$start = time();
&nbsp;&nbsp;while(true)
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;$data = fgets($f);
&nbsp;&nbsp;&nbsp;&nbsp;if ($data &amp;&amp; $data!=&quot;&#92;n&quot;)
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo &quot;SERIAL RX:&quot;.$data;

&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&#125;
&#125;
fclose($f);

?&gt;

</textarea><br/><br/>测试结果：<br/>root@raspberrypi:~/phpComSelect# php fopenFromRaspberry.php <br/>SERIAL RX:TTest UART : Uart will ouput the ASCII 123456 if it is right!<br/>SERIAL RX:123456<br/><br/>PHP的select性能测试：<br/>http://blog.163.com/james_huangjian/blog/static/17804934520123126264385/<br/>上文的下载的：simplehttpd.tar.gz 在台湾没有下载到，没有想到在Gaston兄弟的网上找到了，神奇了，如下：<br/>http://gastonwu.com/tmp/simplehttpd.tar.gz<br/><br/><br/>2013年再次做多串口的select实现如下，该功能在raspberry pi里调试通过：<br/><textarea name="code" class="php" rows="15" cols="100">
&lt;?php&nbsp;&nbsp;
//Error_reporting(E_ALL);&nbsp;&nbsp;
error_reporting(E_ERROR &#124; E_WARNING &#124; E_PARSE);
//Error_reporting(0);&nbsp;&nbsp;
$hosts = array(&quot;/dev/ttyUSB0&quot; ,&quot;/dev/ttyUSB1&quot; ,&quot;/dev/ttyUSB2&quot; ,&quot;/dev/ttyUSB3&quot; ,&quot;/dev/ttyUSB4&quot; ,&quot;/dev/ttyUSB5&quot; ,&quot;/dev/ttyUSB6&quot; ,&quot;/dev/ttyUSB7&quot;);&nbsp;&nbsp;
&nbsp;&nbsp;
$timeout = 1;&nbsp;&nbsp;
$status = array ();&nbsp;&nbsp;
$sockets = array ();&nbsp;&nbsp;
$c = stream_context_create(array(&#039;dio&#039; =&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;array(&#039;data_rate&#039; =&gt; 115200,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;data_bits&#039; =&gt; 8,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;stop_bits&#039; =&gt; 1,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;parity&#039; =&gt; 0,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;flow_control&#039; =&gt; 0,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;is_canonical&#039; =&gt; 1)));&nbsp;&nbsp;
foreach($hosts as $id =&gt;$host)&nbsp;&nbsp;
&#123;&nbsp;&nbsp;
&nbsp;&nbsp;if(file_exists($host) )&nbsp;&nbsp;
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;if (PATH_SEPARATOR != &quot;;&quot;) &#123;
&nbsp;&nbsp;&nbsp;&nbsp;$filename = $host;
&nbsp;&nbsp;&#125; else &#123;
&nbsp;&nbsp;&nbsp;&nbsp;$filename = $host;
&nbsp;&nbsp;&#125;


&nbsp;&nbsp;$s = fopen($filename, &quot;r+&quot;, false, $c);&nbsp;&nbsp;
&nbsp;&nbsp;//stream_set_blocking( $s, true );
&nbsp;&nbsp;stream_set_blocking( $s, false);
&nbsp;&nbsp;if ($s)
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;$data = fgets($s);
&nbsp;&nbsp;&nbsp;&nbsp;$sockets[$id] = $s; 
&nbsp;&nbsp;&nbsp;&nbsp;if ($data &amp;&amp; $data!=&quot;&#92;n&quot;)
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo &quot;SERIAL RX:&quot;.$data;

&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&#125;&nbsp;&nbsp;
&nbsp;&nbsp;&#125;&nbsp;&nbsp;
&#125;
while (count($sockets))&nbsp;&nbsp;
&#123;&nbsp;&nbsp;
&nbsp;&nbsp;$read = $sockets;&nbsp;&nbsp;
&nbsp;&nbsp;$write = null;&nbsp;&nbsp;
&nbsp;&nbsp;echo &quot;&#92;r&#92;n&lt;span&gt;&quot;;
&nbsp;&nbsp;var_dump($read);
&nbsp;&nbsp;echo &quot;&lt;/span&gt;&#92;r&#92;n&quot;;
&nbsp;&nbsp;$n =&nbsp;&nbsp;stream_select($read,$write,$e=null,$timeout);&nbsp;&nbsp;
&nbsp;&nbsp;if ($n === false)&nbsp;&nbsp; 
&nbsp;&nbsp;&#123;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;break;&nbsp;&nbsp;
&nbsp;&nbsp;&#125; else if ($n === 0) &#123;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;/* timed out */&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;$data = &quot;&#92;nERROR:&quot;.&quot; Com-N &quot;.&quot;timed out&quot;;&nbsp;&nbsp;
&nbsp;&nbsp;&#125; else if ($n &gt; 0) &#123;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;foreach ($read as $r)&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&#123;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$id = array_search($r, $sockets);&nbsp;&nbsp;
&nbsp;&nbsp;echo &quot;&#92;r&#92;nread from ttyUSB:&quot;.$hosts[$id].&quot;&#92;r&#92;n&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$data = fgets($r);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($data &amp;&amp; $data!=&quot;&#92;n&quot;)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp; //print_r($read);
&nbsp;&nbsp; echo &quot;Select:&quot;.$data;
&nbsp;&nbsp; //fclose($r);
&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; //unset($sockets[$id]);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;&nbsp;&nbsp;
&nbsp;&nbsp;&#125;
&#125;&nbsp;&nbsp;
?&gt;&nbsp;&nbsp;

</textarea>
]]>
</description>
</item><item>
<link>http://jackxiang.com/post/4803/#blogcomment63371</link>
<title><![CDATA[[评论] [个人原创]在Centos6.0机器上安装PHP的 libevent PECL Package 扩展步骤及实例，以及实现多个USB转串口的读写实践成功 ,可以用select函数。]]></title> 
<author>bokig793 &lt;fsadfasdfasfa@163.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Sun, 20 Nov 2011 06:17:05 +0000</pubDate> 
<guid>http://jackxiang.com/post/4803/#blogcomment63371</guid> 
<description>
<![CDATA[ 
	丢人了~~~
]]>
</description>
</item><item>
<link>http://jackxiang.com/post/4803/#blogcomment63375</link>
<title><![CDATA[[评论] [个人原创]在Centos6.0机器上安装PHP的 libevent PECL Package 扩展步骤及实例，以及实现多个USB转串口的读写实践成功 ,可以用select函数。]]></title> 
<author>bokig194 &lt;fsadfasdfasfa@163.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Sun, 20 Nov 2011 06:23:33 +0000</pubDate> 
<guid>http://jackxiang.com/post/4803/#blogcomment63375</guid> 
<description>
<![CDATA[ 
	好美.谢谢!祝你快乐
]]>
</description>
</item>
</channel>
</rss>