Java JSch ChannelSftp退出状态始终为-1

Java JSch ChannelSftp退出状态始终为-1,java,sftp,jsch,Java,Sftp,Jsch,我使用JSch库来开发SFTP客户机 问题是get和put方法的状态都是-1 这是我的密码: class SftpClient { private static final Logger LOG = Logger.getLogger(SftpClient.class); /** Connection port number */ public static final int PORT = 22; /** SECURED protocol name */

我使用JSch库来开发SFTP客户机

问题是
get
put
方法的状态都是-1

这是我的密码:

class SftpClient {
    private static final Logger LOG = Logger.getLogger(SftpClient.class);

    /** Connection port number */
    public static final int PORT = 22;

    /** SECURED protocol name */
    private static final String PROTOCOL = "sftp";

    /** Connection time out in milliseconds */
    public static final int TIME_OUT = 5000;

    /** This class serves as a central configuration point, and as a factory for Session objects configured with these settings */
    private JSch _client;
    /** A session represents a connection to a SSH server */
    private Session _session;
    /** Channel connected to a SECURED server (as a subsystem of the SSH server) */
    private ChannelSftp _channelSftp;

    /**
     * Value returned by the last executed command.
     */
    private int _exitValue;

    /**
     * Computer contains the url, the login and the password to connect.
     */
    private Computer _computer;

    /**
     * Initialize a SECURED client
     * @param target - Machine we want to connect to
     */
    public SftpClient(Computer target) {
        _client = new JSch();
        _computer = target;
    }

    protected void connect() throws Exception {
        try {
            if (_client == null) {
                _client = new JSch();
            }
            if (_session == null) {
                _session = _client.getSession(_computer.getLogin(), _computer.getUrl(), PORT);
                Properties props = new Properties();
                props.put("StrictHostKeyChecking", "no");
                props.put("compression.s2c", "zlib,none");
                props.put("compression.c2s", "zlib,none");
                _session.setConfig(props);
                _session.setPassword(_computer.getPassword());
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Connecting to "+_computer.getUrl()+" with login "+_computer.getLogin()+"...");
                }
            }
            if (!_session.isConnected()) {
                _session.connect(TIME_OUT);
            }
            // disconnect previous channel if it has not been killed properly
            if (_channelSftp != null && _channelSftp.isConnected()) {
                _channelSftp.disconnect();
            }
            _channelSftp = (ChannelSftp) _session.openChannel(PROTOCOL);
            _channelSftp.connect();
            if (LOG.isInfoEnabled()) {
                LOG.info("Connected to "+_computer.getUrl()+" with login "+_computer.getLogin());
            }
        } catch(JSchException e) {
            LOG.error("Auth failed", e);
            throw e;
        }
    }

    protected void connect(String path) throws Exception {
        connect();
        if (_channelSftp != null && _channelSftp.isConnected()) {
            _channelSftp.cd(path);
        }
    }

    public boolean get(final String remoteDirectory, final String remoteFile, final String localDirectory) throws Exception {
        boolean res = false;
        if (LOG.isInfoEnabled()) {
            LOG.info("Download file "+remoteDirectory+"/"+remoteFile+" from "+_computer+" in "+localDirectory);
        }
        if (remoteDirectory != null && remoteFile != null && !remoteFile.isEmpty() && localDirectory != null) {
            try {
                // connect to the server and change directory
                connect(remoteDirectory);
                // change local directory
                _channelSftp.lcd(localDirectory);
                // download the file, keeping the same name
                _channelSftp.get(remoteFile, remoteFile);
                // update exit value
                _exitValue = _channelSftp.getExitStatus();

                if (_exitValue == 0) {
                    res = true;
                }
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Exit status is: "+_exitValue);
                }
            } catch(SftpException e){
                LOG.error("Auth failed", e);
                throw e;
            } finally {
                if (_channelSftp != null && _channelSftp.isConnected()) {
                    _channelSftp.disconnect();
                    _channelSftp.exit();
                }
            }
        } else {
            LOG.warn("Check remoteDirectory ('"+remoteDirectory+"') or remoteFile ('"+remoteFile+"') or localDirectory ('"+localDirectory+"').");
        }
        return res;
    }

    public void put(final File localFile, final String destPath) throws Exception {
        if (LOG.isInfoEnabled()) {
            LOG.info("Send file "+localFile+" to "+_computer+" in "+destPath);
        }
        if (localFile == null) {
            _exitValue = -1;
            LOG.error("The given local file is null. Aborting tranfer.");
            return;
        }
        if (!localFile.exists()) {
            _exitValue = -1;
            LOG.error("The given local file '"+localFile+"' does not exist. Aborting tranfer.");
            return;
        }
        final InputStream input = new FileInputStream(localFile);
        if (input == null || input.available() <= 0) {
            _exitValue = -1;
            LOG.error("Cannot read file "+localFile);
            return;
        }
        try {
            connect(destPath);
            _channelSftp.put(input, localFile.getName());
            _exitValue = _channelSftp.getExitStatus();
            if (LOG.isDebugEnabled()) {
                LOG.debug("Exit status is: "+_exitValue);
            }
        } catch(SftpException e){
            LOG.error("Auth failed", e);
            throw e;
        } finally {
            if (_channelSftp != null && _channelSftp.isConnected()) {
                _channelSftp.disconnect();
                _channelSftp.exit();
            }
            IOUtils.closeQuietly(input);
        }
    }

    public void disconnect() {
        if (_channelSftp != null && _channelSftp.isConnected()) {
            _channelSftp.disconnect();
            _channelSftp.exit();
        }
        if (_session != null && _session.isConnected()) {
            _session.disconnect();
            if (LOG.isInfoEnabled()) {
                LOG.info("SECURED FTP disconnected");
            }
        }
    }
}
类SftpClient{
私有静态最终记录器LOG=Logger.getLogger(SftpClient.class);
/**连接端口号*/
公共静态最终int端口=22;
/**安全协议名称*/
专用静态最终字符串协议=“sftp”;
/**连接超时(毫秒)*/
公共静态最终整数超时=5000;
/**此类用作中心配置点,并用作使用这些设置配置的会话对象的工厂*/
私人JSch_客户;
/**会话表示到SSH服务器的连接*/
非公开会议;
/**连接到安全服务器的通道(作为SSH服务器的子系统)*/
专用信道SFTP _信道SFTP;
/**
*上次执行的命令返回的值。
*/
私人内部存在价值;
/**
*计算机包含url、登录名和连接密码。
*/
专用计算机(u),;
/**
*初始化安全客户端
*@param target-我们要连接的机器
*/
公共SftpClient(计算机目标){
_client=newjsch();
_计算机=目标;
}
受保护的void connect()引发异常{
试一试{
如果(_client==null){
_client=newjsch();
}
如果(_session==null){
_会话=_client.getSession(_computer.getLogin(),_computer.getUrl(),PORT);
Properties props=新属性();
道具放置(“钥匙检查”、“否”);
props.put(“compression.s2c”、“zlib,none”);
props.put(“compression.c2s”、“zlib,none”);
_session.setConfig(props);
_session.setPassword(_computer.getPassword());
if(LOG.isDebugEnabled()){
调试(“使用登录名“+”连接到“+”计算机.getUrl()+”);
}
}
如果(!\u session.isConnected()){
_会话连接(超时);
}
//如果未正确关闭上一个通道,请断开其连接
如果(_channelSftp!=null&&u channelSftp.isConnected()){
_channelSftp.disconnect();
}
_channelSftp=(channelSftp)\ u session.openChannel(协议);
_channelSftp.connect();
if(LOG.isInfoEnabled()){
LOG.info(“通过登录名“+”连接到“+”计算机.getUrl()+”);
}
}捕获(JSCHEException e){
日志错误(“身份验证失败”,e);
投掷e;
}
}
受保护的void connect(字符串路径)引发异常{
connect();
如果(_channelSftp!=null&&u channelSftp.isConnected()){
_channelSftp.cd(路径);
}
}
公共布尔get(最终字符串remoteDirectory、最终字符串remoteFile、最终字符串localDirectory)引发异常{
布尔res=false;
if(LOG.isInfoEnabled()){
LOG.info(“从“+localDirectory”中的“+\u computer+”下载文件“+remoteDirectory+”/“+remoteFile+”);
}
if(remoteDirectory!=null&&remoteFile!=null&&remoteFile.isEmpty()&&localDirectory!=null){
试一试{
//连接到服务器并更改目录
连接(远程目录);
//更改本地目录
_channelSftp.lcd(localDirectory);
//下载文件,保持相同的名称
_channelSftp.get(remoteFile,remoteFile);
//更新退出值
_exitValue=_channelSftp.getExitStatus();
如果(_exitValue==0){
res=真;
}
if(LOG.isDebugEnabled()){
调试(“退出状态为:”+_exitValue);
}
}捕获(SFTPE例外){
日志错误(“身份验证失败”,e);
投掷e;
}最后{
如果(_channelSftp!=null&&u channelSftp.isConnected()){
_channelSftp.disconnect();
_channelSftp.exit();
}
}
}否则{
LOG.warn(“检查remoteDirectory(“+remoteDirectory+”)或remoteFile(“+remoteFile+”)或localDirectory(“+localDirectory+”)”);
}
返回res;
}
公共void put(最终文件localFile,最终字符串destPath)引发异常{
if(LOG.isInfoEnabled()){
LOG.info(“将文件“+localFile+”发送到“+destPath”中的“+\u computer+”);
}
if(localFile==null){
_exitValue=-1;
LOG.error(“给定的本地文件为null。正在中止传输”);
返回;
}
如果(!localFile.exists()){
_exitValue=-1;
LOG.error(“给定的本地文件''+localFile+''不存在。正在中止传输”);
返回;
}
最终输入流输入=新文件输入流(本地文件);

如果(input==null | | input.available()查看源代码,它看起来是ExitStatus,但没有为SFTP实现

channel.setExitStatus(reason_code);
仅针对会话类中的以下两种情况实现

case SSH_MSG_CHANNEL_OPEN_FAILURE:
case SSH_MSG_CHANNEL_REQUEST:

对于我测试过的成功场景,这两种情况至少都不会被调用。

因此无法从服务器获取回复代码?如何知道请求是否成功?请检查此选项,以便唯一的方法是使用JSch示例中的
checkAck()
方法……无论如何,谢谢。