这是我第一次在这里发帖提问,所以请耐心等待。这个问题让我的智慧结束了。下面详细描述了这个问题。我正在寻找的是运行phpseclib脚本后发生以下错误的潜在原因和可能的补救措施......
致命错误:/home/electroline_admin/orders.electrolineelectronics.com/classes/phpseclib/Net/SSH2.php:1075中未捕获的异常'RuntimeException',消息'连接已被服务器关闭'
堆栈追踪:
/home/electroline_admin/orders.electrolineelectronics.com/classes/phpseclib/Net/SSH2.php(1877年): phpseclib \ Net \ SSH2-> _connect()[内部函数]: phpseclib \ Net \ SSH2-> _login('electroline','Bitter8Steal_Wr ...')
/home/electroline_admin/orders.electrolineelectronics.com/classes/phpseclib/Net/SFTP.php(394): call_user_func_array(Array,Array)
/home/electroline_admin/orders.electrolineelectronics.com/classes/class.orders.php(4974): phpseclib \ Net \ SFTP->登录('electroline','Bitter8Steal_Wr ...')
/home/electroline_admin/orders.electrolineelectronics.com/live_orders_test.php(31): orders-> ftp_in_nd(Array,'1383317685.md5E ...','/ home / electroli ...')
抛出了{main} /home/electroline_admin/orders.electrolineelectronics.com/classes/phpseclib/Net/SSH2.php 在线1075 electroline_admin @ ps80038:〜$ / usr / local / php54 / bin / php /home/electroline_admin/orders.electrolineelectronics.com/live_orders_test.php
所有关于类似问题的勤奋研究,但似乎没有任何指向有意义的答案。我最初的怀疑是存在超时问题,因为这个脚本正在调用并提取各种数量的大量文件。所以我增加了超时限制,但未能解决问题。
任何见解都将深表感谢。感谢!!!
下面提供详细的代码概述....
导致错误的代码如下......
public function pending_ftp()
{
$dumped_arr = array('MAM');
$cust_query = "SELECT DISTINCT `ID` AS ID,`CHUB` AS CH FROM `$this->tbl_cu`";
$res_cust = $this->query($cust_query);
if($res_cust[1])
{
while($cust_arr = mysql_fetch_array($res_cust[0],MYSQL_ASSOC))
{
$cust = $cust_arr['ID'];
$chub = $cust_arr['CH'];
if($chub == 'Y') $stg = $this->chub_ftp_settings($cust);
elseif($cust == 'QBD') $stg = array('URL' => 'edi.esadmin.com','USR' => 'Electroline','PSW' => 'tVd&hP4','PRT' => 21,'DIR' => '/to_Electroline');
else $stg = false;
$pend_dir = '/home/electroline_admin/orders.electrolineelectronics.com/pending/'.strtolower($cust);
if($stg)
{
$new_files = $this->ftp_get_filelist($stg); // METHOD CALLING PHPSECLIB CALLABLE
foreach($new_files as $inx => $file_path)
{
$file_info = pathinfo($file_path);
$file = $file_info['basename'];
$pend_path = $pend_dir.'/'.$file;
$ftp_sts = $this->ftp_in_nd($stg,$file,$pend_path); // METHOD CALLING PHPSECLIB CALLABLE
}
}
elseif(in_array($cust,$dumped_arr))
{
$dump_dir = '/home/electroline_admin/orders.electrolineelectronics.com/dump/'.strtolower($cust);
$dump_files = scandir($dump_dir);
$not_a_file = array('.','..');
foreach($dump_files as $inx => $file)
{
if(!in_array($file,$not_a_file))
{
$dump_path = $dump_dir.'/'.$file;
$pend_path = $pend_dir.'/'.$file;
if(file_exists($dump_path)) $dump_copy = copy($dump_path,$pend_path);
}
}
}
}
}
}
...包含phpseclib可调用的具体方法如下
public function ftp_in_nd($settings,$remote_file,$local_path)
{
if(isset($settings))
{
$furl = $settings['URL'];
$fusr = $settings['USR'];
$fpwd = $settings['PSW'];
$fprt = is_numeric($settings['PRT']) && $settings['PRT'] > 0 ? $settings['PRT'] : 21;
$fdir = strlen($settings['DIR']) > 0 ? $settings['DIR'] : '';
if($fprt == 22)
{
$fcon = new \phpseclib\Net\SFTP($furl,$fprt,30); // PHPSECLIB
if($fcon->login($fusr,$fpwd)) // PHPSECLIB
{
$fmsg = "SFTP LOGIN SUCCESS ($fusr): $furl".(is_numeric($fprt) ? " on port $fprt" : '')." on ".date('Y-m-d @ H:i:s',time())."\r\n";
$fmsg .= "FILE DOWNLOAD ATTEMPT ".date('Y-m-d @ H:i:s',time())."\r\n";
$fcon->chdir($fdir);
if($fcon->get($remote_file,$local_path)) // PHPSECLIB
{
$fmsg .= "FILE DOWNLOADED ".date('Y-m-d @ H:i:s',time())."\r\n";
if(file_exists($local_path))
{
$fmsg .= "DOWNLOAD SUCCESSFULLY VERIFIED ".date('Y-m-d @ H:i:s',time())."\r\n";
$fstat = "SUCCESS";
}
else
{
$fmsg .= "DOWNLOAD NOT VERIFIED ".date('Y-m-d @ H:i:s',time())."\r\n";
$fstat = "UNVERIFIED";
}
goto bottom;
}
else
{
$fmsg .= "FILE DOWNLOAD FAIL ".date('Y-m-d @ H:i:s',time())."\r\n";
$fstat = "FAIL";
goto bottom;
}
}
else
{
$fmsg .= "SFTP LOGIN FAIL ($fusr): file transfer attempt aborted on ".date('Y-m-d @ H:i:s',time())."\r\n";
$fstat = "FAIL";
goto bottom;
}
}
else
{
if($fcon = ftp_connect($furl,(is_numeric($fprt) ? $fprt : 21)))
{
$fmsg = "FTP CONNECT SUCCESS: $furl".(is_numeric($fprt) ? " on port $fprt" : '')." on ".date('Y-m-d @ H:i:s',time())."\r\n";
if(ftp_login($fcon,$fusr,$fpwd))
{
$fmsg .= "FTP LOGIN SUCCESS ($fusr): $furl".(is_numeric($fprt) ? " on port $fprt" : 21)." on ".date('Y-m-d @ H:i:s',time())."\r\n";
$fmsg .= "FILE DOWNLOAD ATTEMPT ".date('Y-m-d @ H:i:s',time())."\r\n";
ftp_chdir($fcon,$fdir);
if(ftp_get($fcon,$local_path,$remote_file,FTP_BINARY))
{
$fmsg .= "FILE DOWNLOADED ".date('Y-m-d @ H:i:s',time())."\r\n";
if(file_exists($local_path))
{
$fmsg .= "DOWNLOAD SUCCESSFULLY VERIFIED ".date('Y-m-d @ H:i:s',time())."\r\n";
$fstat = "SUCCESS";
}
else
{
$fmsg .= "FILE DOWNLOAD NOT VERIFIED ".date('Y-m-d @ H:i:s',time())."\r\n";
$fstat = "UNVERIFIED";
}
goto bottom;
}
else
{
$fmsg .= "FILE DOWNLOAD FAIL ".date('Y-m-d @ H:i:s',time())."\r\n";
$fstat = "FAIL";
goto bottom;
}
}
else
{
$fmsg .= "FTP LOGIN FAIL ($fusr): file transfer attempt aborted on ".date('Y-m-d @ H:i:s',time())."\r\n";
$fstat = "FAIL";
goto bottom;
}
}
else
{
$fmsg = "FTP CONNECT FAIL: file transfer attempt aborted on ".date('Y-m-d @ H:i:s',time())."\r\n";
$fstat = "FAIL";
goto bottom;
}
}
}
else
{
$fmsg = "FTP SETTINGS NOT PROVIDED: file transfer attempt aborted on ".date('Y-m-d @ H:i:s',time())."\r\n";
$fstat = "FAIL";
goto bottom;
}
bottom:
if(!isset($fmsg)) $fmsg = "FTP NOT PROCESSED: process abandoned on ".date('Y-m-d @ H:i:s',time())."; check settings and reprocess\r\n";
if(!isset($fstat)) $fstat = "FAIL";
$stat['SID'] = $fstat;
$stat['MSG'] = $fmsg;
return $stat;
}
从我自己的行动和情报收集中,当从phpseclib SSH2类调用此方法时,似乎发生了失败的连接......
function _connect()
{
if ($this->bitmap & self::MASK_CONSTRUCTOR) {
return false;
}
$this->bitmap |= self::MASK_CONSTRUCTOR;
$this->curTimeout = $this->timeout;
$this->last_packet = microtime(true);
if (!is_resource($this->fsock)) {
$start = microtime(true);
$this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->curTimeout);
if (!$this->fsock) {
$host = $this->host . ':' . $this->port;
throw new \RuntimeException(rtrim("Cannot connect to $host. Error $errno. $errstr"));
}
$elapsed = microtime(true) - $start;
$this->curTimeout-= $elapsed;
if ($this->curTimeout <= 0) {
$this->is_timeout = true;
return false;
}
}
/* According to the SSH2 specs,
"The server MAY send other lines of data before sending the version
string. Each line SHOULD be terminated by a Carriage Return and Line
Feed. Such lines MUST NOT begin with "SSH-", and SHOULD be encoded
in ISO-10646 UTF-8 [RFC3629] (language is not specified). Clients
MUST be able to process such lines." */
$temp = '';
$extra = '';
while (!feof($this->fsock) && !preg_match('#^SSH-(\d\.\d+)#', $temp, $matches)) {
if (substr($temp, -2) == "\r\n") {
$extra.= $temp;
$temp = '';
}
if ($this->curTimeout) {
if ($this->curTimeout < 0) {
$this->is_timeout = true;
return false;
}
$read = array($this->fsock);
$write = $except = null;
$start = microtime(true);
$sec = floor($this->curTimeout);
$usec = 1000000 * ($this->curTimeout - $sec);
// on windows this returns a "Warning: Invalid CRT parameters detected" error
// the !count() is done as a workaround for <https://bugs.php.net/42682>
if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) {
$this->is_timeout = true;
return false;
}
$elapsed = microtime(true) - $start;
$this->curTimeout-= $elapsed;
}
$temp.= fgets($this->fsock, 255);
}
**if (feof($this->fsock)) {
throw new \RuntimeException('Connection closed by server');
} // SCRIPT FAILS HERE!!! **
$this->identifier = $this->_generate_identifier();
if (defined('NET_SSH2_LOGGING')) {
$this->_append_log('<-', $extra . $temp);
$this->_append_log('->', $this->identifier . "\r\n");
}
$this->server_identifier = trim($temp, "\r\n");
if (strlen($extra)) {
$this->errors[] = utf8_decode($extra);
}
if ($matches[1] != '1.99' && $matches[1] != '2.0') {
throw new \RuntimeException("Cannot connect to SSH $matches[1] servers");
}
fputs($this->fsock, $this->identifier . "\r\n");
$response = $this->_get_binary_packet();
if ($response === false) {
throw new \RuntimeException('Connection closed by server');
}
if (ord($response[0]) != NET_SSH2_MSG_KEXINIT) {
throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT');
}
if (!$this->_key_exchange($response)) {
return false;
}
$this->bitmap|= self::MASK_CONNECTED;
return true;
}
答案 0 :(得分:0)
嗯,我能够很好地连接:
<?php
include('Net/SSH2.php');
define('NET_SSH2_LOGGING', 2);
$ssh = new Net_SSH2('orders.electrolineelectronics.com');
$ssh->login('zzz', 'zzz');
echo $ssh->getLog();
我的意思是,我无法成功进行身份验证,但我可以进行身份验证尝试。
鉴于此,我的猜测是问题在于试图建立连接的计算机。与环境有关的东西。也许您安装了selinux,默认情况下会阻止fsockopen正常工作:
或者您的主机可能orders.electrolineelectronics.com
指向其他未安装SSH服务器的IP地址。
可能是任何数量的问题,但事实上,我能够与phpseclib连接得很好,这让我觉得问题是环境问题。特别是因为它在实际设法发送任何数据之前就已经死了(假设你的分析是正确的)。