之前工作中必须和国外服务器打交道,延迟和丢包问题有时候非常严重,已经到了不可忍受的地步,输入一条sql都是很费劲的事情,google搜了一遍没有找到非阻塞的ssh客户端,PHP有SSH2扩展,利用标准输入输出理论上可以实现一个基于命令的SSH客户端,这样就解决了网络问题带来的不便,于是开发了一个PHP非阻塞SSH客户端.
价值:基于命令,最大程度解决了网络延迟和丢包问题,windows和Linux下测试通过.
不足:没有自动补全功能,没有sftp和scp等其他功能,没有颜色和粗体显示,个别情况下显示上不是很完美,因为现在基本不用它了,所以暂时先不进行改进.
因为是框架中的一个类,所以个别通用函数(比如debug_print())需要自己提供,我这里就不改写了,代码如下:
-
<?php
-
class FSSH{
-
private $conn;
-
private $shell;
-
-
-
-
-
-
-
function __construct($host,$user,$key){
-
if(emptyempty($host['addr'])){
-
debug_print('Host cant't be emptyempty',E_USER_ERROR);
-
}
-
if(emptyempty($host['fp'])){
-
debug_print('finger print is not specified',E_USER_ERROR);
-
}
-
$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) || emptyempty($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,