帝国CMS模板大全
www.admin99.cn
www.92cms.cn 帝国CMS模板下载站!,情怀,养站,二次开发!源码需求比较大的一站式会员下载,价更省!!!

php无阻塞SSH客户端实例 - php环境安装

php无阻塞SSH客户端实例

之前工作中必须和国外服务器打交道,延迟和丢包问题有时候非常严重,已经到了不可忍受的地步,输入一条sql都是很费劲的事情,google搜了一遍没有找到非阻塞的ssh客户端,PHP有SSH2扩展,利用标准输入输出理论上可以实现一个基于命令的SSH客户端,这样就解决了网络问题带来的不便,于是开发了一个PHP非阻塞SSH客户端.

价值: 基于命令,最大程度解决了网络延迟和丢包问题,windows和Linux下测试通过.

不足:没有自动补全功能,没有sftp和scp等其他功能,没有颜色和粗体显示,个别情况下显示上不是很完美,因为现在基本不用它了,所以暂时先不进行改进.

因为是框架中的一个类,所以个别通用函数(比如debug_print())需要自己提供,我这里就不改写了,代码如下:

  • <?php 
  • class  FSSH{ 
  •  private   $conn
  •  private   $shell
  •  
  •  /**  
  •  * key=String 密码认证,key=array('pub'=>,'pri'=>,'type'=>,'phrase'=>)密钥认证  
  •  * 密钥认证type分为两种:ssh-rsa,ssh-dss   
  •  * $host[addr]=String 地址,$host['fp']=array() 服务器指纹  
  •  */  
  •  function  __construct( $host , $user , $key ){ 
  •   if ( empty empty ( $host [ 'addr' ])){ 
  •    debug_print('Host cant' t be  empty empty ',E_USER_ERROR); 
  •   } 
  •   if ( empty empty ( $host [ 'fp' ])){ 
  •    debug_print('finger print is not specified' ,E_USER_ERROR); 
  •   }//开源代码phpfensi.com  
  •   $this ->stdin= fopen ( 'php://stdin' , 'r' ); 
  •   $this ->stdout= fopen ( 'php://stdout' , 'w' ); 
  •   if (false!== strpos ( $host [ 'addr' ], ':' )){ 
  •    $temp = explode ( ':' , $host [ 'addr' ]); 
  •    $host [ 'addr' ]= $temp [0]; 
  •    $port = $temp [1]; 
  •   }else
  •    $port =22; 
  •   } 
  •   if ( is_string ( $key ) ||  empty empty ( $key [ 'type' ])){ 
  •    $methods =null; 
  •   }else
  •    $methods = array ( 'hostkey' => $key [ 'type' ]); 
  •   } 
  •   $conn =ssh2_connect( $host [ 'addr' ], $port , $methods , array ( 'disconnect' => array ( $this , 'disconnect' ))); 
  •   $fp =ssh2_fingerprint( $conn ,SSH2_FINGERPRINT_MD5); 
  •   $success =false; 
  •   $fpOK =false; 
  •   if (in_array( $fp , $host [ 'fp' ])){ 
  •    $fpOK =true; 
  •   }else
  •    fwrite($this ->stdout, "$fpnIs fingerprint OK ?(y/n)" ); 
  •    $input = strtolower (stream_get_line( $this ->stdin,1)); 
  •    if ( $input == 'y' ){ 
  •     $fpOK =true; 
  •    }else
  •     $fpOK =false; 
  •    } 
  •   } 
  •   if ( $fpOK ){ 
  •    if ( is_array ( $key )){ 
  •     if  (ssh2_auth_pubkey_file( $conn , $user , $key [ 'pub' ], $key [ 'pri' ], $key [ 'phrase' ])){ 
  •      $success =true; 
  •     }else
  •      debug_print('Public Key Authentication Failed' ,E_USER_ERROR); 
  •     } 
  •    }elseif ( is_string ( $key )){ 
  •     if (ssh2_auth_password( $conn , $user , $key )){ 
  •      $success =true; 
  •     }else
  •      debug_print('Password Authentication Failed' ,E_USER_ERROR); 
  •     } 
  •    } 
  •   }else
  •    debug_print('Fingerprint is invalid' ,E_USER_ERROR); 
  •   } 
  •   if ( $success ){ 
  •    $this ->conn= $conn
  •    $this ->shell=ssh2_shell( $conn ,null,null,1024); 
  •   } 
  •   return   $success
  •  } 
  •  
  •  function  shell(){ 
  •   //最后一条命令  
  •   $last = ''
  •   //先结束shell,再结束while  
  •   $signalTerminate =false; 
  •   while (true){ 
  •    $cmd = $this -> fread ( $this ->stdin); 
  •    $out =stream_get_contents( $this ->shell,1024); 
  •    if (! empty empty ( $out and  ! empty empty ( $last )){ 
  •     $l1 = strlen ( $out ); 
  •     $l2 = strlen ( $last ); 
  •     $l = $l1 > $l2 ? $l2 : $l1
  •     $last = substr ( $last , $l ); 
  •     $out = substr ( $out , $l ); 
  •    } 
  •    echo  ltrim( $out ); 
  •    if ( $signalTerminate ){ 
  •     break
  •    } 
  •    if (in_array(trim( $cmd ), array ( 'exit' ))){ 
  •     $signalTerminate =true; 
  •    } 
  •    if (! empty empty ( $cmd )){ 
  •     $last = $cmd
  •     fwrite($this ->shell, $cmd ); 
  •    } 
  •   } 
  •  } 
  •  
  •  //解决windows命令行的读取问题,没有别的办法了。  
  •  private   function   fread ( $fd ){ 
  •   static   $data = ''
  •   $read  =  array ( $fd ); 
  •   $write  =  array (); 
  •   $except  =  array (); 
  •   $result  = stream_select( $read , $write , $except ,0,1000); 
  •   if ( $result  === false) 
  •    debug_print('stream_select failed' ,E_USER_ERROR); 
  •   if ( $result  !== 0){ 
  •    $c = stream_get_line( $fd ,1); 
  •    if ( $c != chr (13)) 
  •     $data .= $c
  •    if ( $c == chr (10)){ 
  •     $t = $data
  •     $data = ''
  •     return   $t
  •    } 
  •   } 
  •  } 
  •  
  •  function  __destruct(){ 
  •   fclose($this ->stdin); 
  •   fclose($this ->stdout); 
  •   $this ->disconnect(); 
  •  } 
  •  
  •  private   function  disconnect(){ 
  •   if ( is_resource ( $this ->conn)){ 
  •    unset($this ->conn); 
  •    fclose($this ->shell); 
  •   } 
  •  } 
  • ?> 

    demo,代码如下:

  • //$ssh=new FSSH(array('addr'=>'x.x.x.x:22','fp'=>array('')),'tunnel',array('pub'=>'E:Identity.pub','pri'=>'E:Identity','type'=>'ssh-rsa'));  
  • $ssh = new  FSSH( array ( 'addr' => '192.168.2.205' , 'fp' => array ( '54ECC700B844DCF0D40554A56C57C01E' )), 'root' , '123456' ); 
  • $ssh ->shell(); 

  • 赞(0)
    版权声明:本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
    文章名称:《php无阻塞SSH客户端实例 - php环境安装》
    文章链接:https://www.admin99.cn/6592
    本站资源仅供个人学习交流,请于下载后24小时内删除,不允许用于商业用途,否则法律问题自行承担。
    QQ站长交流群:953950264

    登录

    找回密码

    注册