免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2876 | 回复: 0

PHPTelnet类改进分享及求教是否有非阻塞的phpTelnet实现 [复制链接]

论坛徽章:
92
CU大牛徽章
日期:2013-11-29 22:26:36CU大牛徽章
日期:2014-02-21 14:21:56CU十二周年纪念徽章
日期:2014-02-21 14:22:02CU大牛徽章
日期:2014-02-21 14:22:07CU大牛徽章
日期:2014-02-21 14:22:09CU大牛徽章
日期:2015-02-28 17:45:342015元宵节徽章
日期:2015-03-06 16:56:38羊年新春福章
日期:2015-02-28 17:42:522015七夕节徽章
日期:2015-09-14 09:24:55CU大牛徽章
日期:2014-02-21 14:22:44CU大牛徽章
日期:2015-02-28 17:48:12CU大牛徽章
日期:2015-02-28 17:47:58
发表于 2015-03-05 15:15 |显示全部楼层
有需求通过php来连接一些telnet服务器,网上找到了一个现成的实现代码(附于最后),使用时发现会等待结果很久才返回,然后发现是获取返回数据的函数读取socket使用了阻塞读取固定长度1000的数据,而返回的数据有时候并没有这么多从而一直等到超时才返回,如下将函数做了改进与大家分享:
  1.         function GetResponse(&$r) {
  2.             echo "Get response...\n";
  3.                 $r='';
  4.                 $unread_bytes = 1;
  5.                 do {
  6.                     var_dump($unread_bytes);
  7.                         $r.=fread($this->fp,$unread_bytes);
  8.                         $s=socket_get_status($this->fp);
  9.                         $unread_bytes = $s['unread_bytes'];
  10.                 } while ($s['unread_bytes']);
  11.         }
复制代码
当然,如果服务器连一个数据也没有的话还是要阻塞。另外一个疑问,因为telnet服务器有时候会主动推送数据过来,而这个PHPTelnet类需要发送命令后才会等待输出,使用这个代码的话就不能及时得到了服务器推送的数据了。不知道大家有没有好的方案来监听telnet服务器推送数据。我的打算是用socket_select的方式来改造这个类实现推送数据的监听。


  1. <?php
  2. /*
  3. PHPTelnet 1.1.1
  4. by Antone Roundy
  5. adapted from code found on the PHP website
  6. public domain
  7. */

  8. class PHPTelnet {
  9.         var $show_connect_error=1;

  10.         var $use_usleep=0;        // change to 1 for faster execution
  11.                 // don't change to 1 on Windows servers unless you have PHP 5
  12.         var $sleeptime=125000;
  13.         var $loginsleeptime=1000000;

  14.         var $fp=NULL;
  15.         var $loginprompt;

  16.         var $conn1;
  17.         var $conn2;
  18.        
  19.         /*
  20.         0 = success
  21.         1 = couldn't open network connection
  22.         2 = unknown host
  23.         3 = login failed
  24.         4 = PHP version too low
  25.         */
  26.         function Connect($server,$user,$pass) {
  27.                 $rv=0;
  28.                 $vers=explode('.',PHP_VERSION);
  29.                 $needvers=array(4,3,0);
  30.                 $j=count($vers);
  31.                 $k=count($needvers);
  32.                 if ($k<$j) $j=$k;
  33.                 for ($i=0;$i<$j;$i++) {
  34.                         if (($vers[$i]+0)>$needvers[$i]) break;
  35.                         if (($vers[$i]+0)<$needvers[$i]) {
  36.                                 $this->ConnectError(4);
  37.                                 return 4;
  38.                         }
  39.                 }
  40.                
  41.                 $this->Disconnect();
  42.                
  43.                 if (strlen($server)) {
  44.                         if (preg_match('/[^0-9.]/',$server)) {
  45.                                 $ip=gethostbyname($server);
  46.                                 if ($ip==$server) {
  47.                                         $ip='';
  48.                                         $rv=2;
  49.                                 }
  50.                         } else $ip=$server;
  51.                 } else $ip='127.0.0.1';
  52.                
  53.                 if (strlen($ip)) {
  54.                         if ($this->fp=fsockopen($ip,23)) {
  55.                                 fputs($this->fp,$this->conn1);
  56.                                 $this->Sleep();
  57.                                
  58.                                 fputs($this->fp,$this->conn2);
  59.                                 $this->Sleep();
  60.                                 $this->GetResponse($r);
  61.                                 $r=explode("\n",$r);
  62.                                 $this->loginprompt=$r[count($r)-1];

  63.                                 fputs($this->fp,"$user\r");
  64.                                 $this->Sleep();

  65.                                 fputs($this->fp,"$pass\r");
  66.                                 if ($this->use_usleep) usleep($this->loginsleeptime);
  67.                                 else sleep(1);
  68.                                 $this->GetResponse($r);
  69.                                 $r=explode("\n",$r);
  70.                                 if (($r[count($r)-1]=='')||($this->loginprompt==$r[count($r)-1])) {
  71.                                         $rv=3;
  72.                                         $this->Disconnect();
  73.                                 }
  74.                         } else $rv=1;
  75.                 }
  76.                
  77.                 if ($rv) $this->ConnectError($rv);
  78.                 return $rv;
  79.         }
  80.        
  81.         function Disconnect($exit=1) {
  82.                 if ($this->fp) {
  83.                         if ($exit) $this->DoCommand('exit',$junk);
  84.                         fclose($this->fp);
  85.                         $this->fp=NULL;
  86.                 }
  87.         }

  88.         function DoCommand($c,&$r) {
  89.                 if ($this->fp) {
  90.                         fputs($this->fp,"$c\r");
  91.                         $this->Sleep();
  92.                         $this->GetResponse($r);
  93.                         $r=preg_replace("/^.*?\n(.*)\n[^\n]*$/","$1",$r);
  94.                 }
  95.                 return $this->fp?1:0;
  96.         }
  97.        
  98.         function GetResponse(&$r) {
  99.                 $r='';
  100.                 do {
  101.                         $r.=fread($this->fp,1000);
  102.                         $s=socket_get_status($this->fp);
  103.                 } while ($s['unread_bytes']);
  104.         }
  105.        
  106.         function Sleep() {
  107.                 if ($this->use_usleep) usleep($this->sleeptime);
  108.                 else sleep(1);
  109.         }
  110.        
  111.         function PHPTelnet() {
  112.                 $this->conn1=chr(0xFF).chr(0xFB).chr(0x1F).chr(0xFF).chr(0xFB).
  113.                         chr(0x20).chr(0xFF).chr(0xFB).chr(0x18).chr(0xFF).chr(0xFB).
  114.                         chr(0x27).chr(0xFF).chr(0xFD).chr(0x01).chr(0xFF).chr(0xFB).
  115.                         chr(0x03).chr(0xFF).chr(0xFD).chr(0x03).chr(0xFF).chr(0xFC).
  116.                         chr(0x23).chr(0xFF).chr(0xFC).chr(0x24).chr(0xFF).chr(0xFA).
  117.                         chr(0x1F).chr(0x00).chr(0x50).chr(0x00).chr(0x18).chr(0xFF).
  118.                         chr(0xF0).chr(0xFF).chr(0xFA).chr(0x20).chr(0x00).chr(0x33).
  119.                         chr(0x38).chr(0x34).chr(0x30).chr(0x30).chr(0x2C).chr(0x33).
  120.                         chr(0x38).chr(0x34).chr(0x30).chr(0x30).chr(0xFF).chr(0xF0).
  121.                         chr(0xFF).chr(0xFA).chr(0x27).chr(0x00).chr(0xFF).chr(0xF0).
  122.                         chr(0xFF).chr(0xFA).chr(0x18).chr(0x00).chr(0x58).chr(0x54).
  123.                         chr(0x45).chr(0x52).chr(0x4D).chr(0xFF).chr(0xF0);
  124.                 $this->conn2=chr(0xFF).chr(0xFC).chr(0x01).chr(0xFF).chr(0xFC).
  125.                         chr(0x22).chr(0xFF).chr(0xFE).chr(0x05).chr(0xFF).chr(0xFC).chr(0x21);
  126.         }
  127.        
  128.         function ConnectError($num) {
  129.                 if ($this->show_connect_error) switch ($num) {
  130.                 case 1: echo '<br />[PHP Telnet] <a href="http://www.geckotribe.com/php-telnet/errors/fsockopen.php">Connect failed: Unable to open network connection</a><br />'; break;
  131.                 case 2: echo '<br />[PHP Telnet] <a href="http://www.geckotribe.com/php-telnet/errors/unknown-host.php">Connect failed: Unknown host</a><br />'; break;
  132.                 case 3: echo '<br />[PHP Telnet] <a href="http://www.geckotribe.com/php-telnet/errors/login.php">Connect failed: Login failed</a><br />'; break;
  133.                 case 4: echo '<br />[PHP Telnet] <a href="http://www.geckotribe.com/php-telnet/errors/php-version.php">Connect failed: Your server\'s PHP version is too low for PHP Telnet</a><br />'; break;
  134.                 }
  135.         }
  136. }

  137. return;
  138. ?>
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

SACC2019中国系统架构师大会

【数字转型 架构演进】SACC2019中国系统架构师大会,7折限时优惠重磅来袭!
2019年10月31日~11月2日第11届中国系统架构师大会(SACC2019)将在北京隆重召开。四大主线并行的演讲模式,1个主会场、20个技术专场、超千人参与的会议规模,100+来自互联网、金融、制造业、电商等领域的嘉宾阵容,将为广大参会者提供一场最具价值的技术交流盛会。

限时七折期:2019年8月31日前


----------------------------------------

大会官网>>
  

北京盛拓优讯信息技术有限公司. 版权所有 16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122
中国互联网协会会员  联系我们:huangweiwei@it168.com
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP