当前位置:编程学习 > JAVA >>

求助!Java里用jsch实现sftp时出现异常:com.jcraft.jsch.JSchException: failed to send channel r

大家好!

我想做的事情:
  用java和jsch实现对远程sftp服务器的如下功能: 
     1,连接。
     2,下载文件。
     3,上传文件。

出现的问题:(详细信息在下面)
com.jcraft.jsch.JSchException: failed to send channel request
at com.jcraft.jsch.Request.write(Request.java:65)
at com.jcraft.jsch.RequestSftp.request(RequestSftp.java:47)
at com.jcraft.jsch.ChannelSftp.start(ChannelSftp.java:190)
at com.jcraft.jsch.Channel.connect(Channel.java:200)
at com.jcraft.jsch.Channel.connect(Channel.java:144)
at com.xuts.test.sftp.util.SftpImplTest.connect(SftpImplTest.java:58)
at com.xuts.test.sftp.util.SftpImplTest.main(SftpImplTest.java:345)

出错地方:
public void connect() 方法里的这一句:
  channel.connect();

public void connect() 方法:(详细代码在下面)
public void connect() {
try {
if (sftp != null) {
System.out.println("sftp is not null");
}
      JSch.setLogger(new MyLogger());
JSch jsch = new JSch();
jsch.getSession(username, host, port);
Session sshSession = jsch.getSession(username, host, port);
System.out.println("Session created.");
sshSession.setPassword(password);
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
sshSession.connect();
System.out.println("Session connected.");
System.out.println("Opening Channel.");
Channel channel = sshSession.openChannel("sftp");
channel.connect();
sftp = (ChannelSftp) channel;
System.out.println("Connected to " + host + ".");
System.out.println("Connect " + (sftp.isConnected()?"successed":"failed"));
} catch (Exception e) {
e.printStackTrace();
}
}




本地配置:
     jdk版本:jdk1.5.0_22
     jsch版本:jsch-0.1.44.jar

sftp服务器:
     sftp版本:SSH-2.0-OpenSSH_5.3



控制台的信息:
Session created.
INFO: Connecting to 43.82.101.237 port 22
INFO: Connection established
INFO: Remote version string: SSH-2.0-OpenSSH_5.3
INFO: Local version string: SSH-2.0-JSCH-0.1.44
INFO: CheckCiphers: aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,3des-ctr,arcfour,arcfour128,arcfour256
INFO: aes256-ctr is not available.
INFO: aes192-ctr is not available.
INFO: aes256-cbc is not available.
INFO: aes192-cbc is not available.
INFO: arcfour256 is not available.
INFO: SSH_MSG_KEXINIT sent
INFO: SSH_MSG_KEXINIT received
INFO: kex: server->client aes128-ctr hmac-md5 none
INFO: kex: client->server aes128-ctr hmac-md5 none
INFO: SSH_MSG_KEXDH_INIT sent
INFO: expecting SSH_MSG_KEXDH_REPLY
INFO: ssh_rsa_verify: signature true
WARN: Permanently added '43.82.101.237' (RSA) to the list of known hosts.
INFO: SSH_MSG_NEWKEYS sent
INFO: SSH_MSG_NEWKEYS received
INFO: SSH_MSG_SERVICE_REQUEST sent
INFO: SSH_MSG_SERVICE_ACCEPT received
INFO: Authentications that can continue: publickey,keyboard-interactive,password
Session connected.
Opening Channel.
INFO: Next authentication method: publickey
INFO: Authentications that can continue: keyboard-interactive,password
INFO: Next authentication method: keyboard-interactive
INFO: Authentications that can continue: password
INFO: Next authentication method: password
INFO: Authentication succeeded (password).
com.jcraft.jsch.JSchException: failed to send channel request
at com.jcraft.jsch.Request.write(Request.java:65)
at com.jcraft.jsch.RequestSftp.request(RequestSftp.java:47)
at com.jcraft.jsch.ChannelSftp.start(ChannelSftp.java:190)
at com.jcraft.jsch.Channel.connect(Channel.java:200)
at com.jcraft.jsch.Channel.connect(Channel.java:144)
at com.xuts.test.sftp.util.SftpImplTest.connect(SftpImplTest.java:58)
at com.xuts.test.sftp.util.SftpImplTest.main(SftpImplTest.java:345)
localFile : D:\prod\metis_app\batch\scabinetbatch\test\1.txt
remotePath:/cygdrive/d/prod/metis_app/batch/scabinetbatch/test/1.txt
*******remotefile.getParent():\cygdrive\d\prod\metis_app\batch\scabinetbatch\test
*******create path failed\cygdrive\d\prod\metis_app\batch\scabinetbatch\test
Exception in thread "main" java.lang.NullPointerException
at com.xuts.test.sftp.util.SftpImplTest.upload(SftpImplTest.java:126)
at com.xuts.test.sftp.util.SftpImplTest.main(SftpImplTest.java:346)



--------------------编程问答-------------------- 下面给出测试代码:(SftpImplTest.java)

package com.xuts.test.sftp.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import com.xuts.test.sftp.Logger.MyLogger;

public class SftpImplTest {

private String host = "43.82.101.237";
private String username = "user";
private String password = "xxxxx";
// private String host = "127.0.0.1";
// private String username = "user";
// private String password = "1sssss";
private int port = 22;
private ChannelSftp sftp = null;
private String localPath = "D:/prod/metis_app/batch/scabinetbatch/test";
private String remotePath = "/cygdrive/d/prod/metis_app/batch/scabinetbatch/test";
private String fileListPath = "D:/prod/metis_app/batch/scabinetbatch/test/file.txt";
private final String seperator = "/";

/**
 * connect server via sftp
 */
public void connect() {
try {
if (sftp != null) {
System.out.println("sftp is not null");
}
      JSch.setLogger(new MyLogger());
JSch jsch = new JSch();
jsch.getSession(username, host, port);
Session sshSession = jsch.getSession(username, host, port);
System.out.println("Session created.");
sshSession.setPassword(password);
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
sshSession.connect();
System.out.println("Session connected.");
System.out.println("Opening Channel.");
Channel channel = sshSession.openChannel("sftp");
channel.connect();
sftp = (ChannelSftp) channel;
System.out.println("Connected to " + host + ".");
System.out.println("Connect " + (sftp.isConnected()?"successed":"failed"));
} catch (Exception e) {
e.printStackTrace();
}
}

/**
 * Disconnect with server
 */
public void disconnect() {
if (this.sftp != null) {
if (this.sftp.isConnected()) {
this.sftp.disconnect();
} else if (this.sftp.isClosed()) {
System.out.println("sftp is closed already");
}
}

}

public void download() {

}

public void download(String directory, String downloadFile,
String saveFile, ChannelSftp sftp) {
try {
sftp.cd(directory);
File file = new File(saveFile);
sftp.get(downloadFile, new FileOutputStream(file));
} catch (Exception e) {
e.printStackTrace();
}
}

/**
 * upload all the files to the server
 */
public void upload() {
List<String> fileList = this.getFileEntryList(fileListPath);
try {
if (fileList != null) {
for (String filepath : fileList) {
String localFile = this.localPath + this.seperator
+ filepath;
File file = new File(localFile);

if (file.isFile()) {
System.out.println("localFile : "
+ file.getAbsolutePath());
String remoteFile = this.remotePath + this.seperator
+ filepath;
System.out.println("remotePath:" + remoteFile);
File rfile = new File(remoteFile);
String rpath = rfile.getParent();
System.out.println("*******remotefile.getParent():"
+ rpath);
try {
createDir(rpath, sftp);
} catch (Exception e) {
System.out.println("*******create path failed"
+ rpath);
}

this.sftp
.put(new FileInputStream(file), file.getName());
System.out.println("=========upload down for "
+ localFile);
}
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (SftpException e) {
e.printStackTrace();
}

}

/**
 * create Directory
 * 
 * @param filepath
 * @param sftp
 */
private void createDir(String filepath, ChannelSftp sftp) {
boolean bcreated = false;
boolean bparent = false;
File file = new File(filepath);
String ppath = file.getParent();
try {
this.sftp.cd(ppath);
bparent = true;
} catch (SftpException e1) {
bparent = false;
}
try {
if (bparent) {
try {
this.sftp.cd(filepath);
bcreated = true;
} catch (Exception e) {
bcreated = false;
}
if (!bcreated) {
this.sftp.mkdir(filepath);
bcreated = true;
}
return;
} else {
createDir(ppath, sftp);
this.sftp.cd(ppath);
this.sftp.mkdir(filepath);
}
} catch (SftpException e) {
System.out.println("mkdir failed :" + filepath);
e.printStackTrace();
}

try {
this.sftp.cd(filepath);
} catch (SftpException e) {
e.printStackTrace();
System.out.println("can not cd into :" + filepath);
}

}

/**
 * get all the files need to be upload or download
 * 
 * @param file
 * @return
 */
private List<String> getFileEntryList(String file) {
ArrayList<String> fileList = new ArrayList<String>();
InputStream in = null;
try {

in = new FileInputStream(file);
InputStreamReader inreader = new InputStreamReader(in);

LineNumberReader linreader = new LineNumberReader(inreader);
String filepath = linreader.readLine();
while (filepath != null) {
fileList.add(filepath);
filepath = linreader.readLine();
}
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (in != null) {
in = null;
}
}

return fileList;
}

/**
 * @return the host
 */
public String getHost() {
return host;
}

/**
 * @param host
 *            the host to set
 */
public void setHost(String host) {
this.host = host;
}

/**
 * @return the username
 */
public String getUsername() {
return username;
}

/**
 * @param username
 *            the username to set
 */
public void setUsername(String username) {
this.username = username;
}

/**
 * @return the password
 */
public String getPassword() {
return password;
}

/**
 * @param password
 *            the password to set
 */
public void setPassword(String password) {
this.password = password;
}

/**
 * @return the port
 */
public int getPort() {
return port;
}

/**
 * @param port
 *            the port to set
 */
public void setPort(int port) {
this.port = port;
}

/**
 * @return the sftp
 */
public ChannelSftp getSftp() {
return sftp;
}

/**
 * @param sftp
 *            the sftp to set
 */
public void setSftp(ChannelSftp sftp) {
this.sftp = sftp;
}

/**
 * @return the localPath
 */
public String getLocalPath() {
return localPath;
}

/**
 * @param localPath
 *            the localPath to set
 */
public void setLocalPath(String localPath) {
this.localPath = localPath;
}

/**
 * @return the remotePath
 */
public String getRemotePath() {
return remotePath;
}

/**
 * @param remotePath
 *            the remotePath to set
 */
public void setRemotePath(String remotePath) {
this.remotePath = remotePath;
}

/**
 * @return the fileListPath
 */
public String getFileListPath() {
return fileListPath;
}

/**
 * @param fileListPath
 *            the fileListPath to set
 */
public void setFileListPath(String fileListPath) {
this.fileListPath = fileListPath;
}

public static void main(String[] args) {
SftpImplTest ftp = new SftpImplTest();
ftp.connect();
ftp.upload();
ftp.disconnect();
System.exit(0);
}


  public static class MyLogger implements com.jcraft.jsch.Logger {
    static java.util.Hashtable name=new java.util.Hashtable();
    static{
      name.put(new Integer(DEBUG), "DEBUG: ");
      name.put(new Integer(INFO), "INFO: ");
      name.put(new Integer(WARN), "WARN: ");
      name.put(new Integer(ERROR), "ERROR: ");
      name.put(new Integer(FATAL), "FATAL: ");
    }
    public boolean isEnabled(int level){
      return true;
    }
    public void log(int level, String message){
      System.err.print(name.get(new Integer(level)));
      System.err.println(message);
    }
  }

}

--------------------编程问答-------------------- public class SFTPImport extends ImportFile {

  private ChannelSftp                    cs;
  // SFTP Session
  private Session                        session;
  // The number of transfered file
  private int                            transferedFileNum;
  private String                         port         = "22";
  // ip address or url
  String                         server;
  String                         username;
  String                         password;
  // file list
  Set<String>                    fileSet;
  // workspace directory
  String                         workspaceDir;
  boolean                        stop        = false;
  int                            originalFileNum;
  
  /**
   * Constructor
   * 
   * @param jobId
   *          job id
   * @param conf
   *          configuration
   * @param workspaceDir
   *          worksapce directory
   * @param task
   *          FileTask
   */
  public SFTPImport(String server, String port, String username, String password, Set<String>  fileSet) {
    this.server = server;
    this.username = username;
    this.password = password;
    this.fileSet = fileSet;
    this.port = port;
  }

  /**
   * Disconnect with FTP/sftp server
   */
  protected void disconnect() {
    // If exists and connected
    if (cs != null && cs.isConnected()) {
      // Disconnect
      logger.info("DISCONNECTING SFTP: " + cs);
      cs.disconnect();
      logger.info("DISCONNECTED SFTP: " + session);
      // Null out the client so it's not serialized
      this.cs = null;
    }
    // If exists and connected
    if (session != null && session.isConnected()) {
      // Disconnect
      logger.info("DISCONNECTING SFTP: " + session);
      session.disconnect();
      logger.info("DISCONNECTED SFTP: " + session);
      // Null out the client so it's not serialized
      this.session = null;
    }
  }

  /**
   * Set sftp session Import files from SFTP Server split fileList into multiply files
   * 
   * @pre run()
   */
  protected void transferFile() throws FileTransferException{

    OutputStream outStream = null;
    InputStream inStream = null;
    logger.info(">>>>>>>CONNECT TO :" + server);
    // set up sftp session
    JSch jsch = new JSch();
    if (port == null) {
      port = "22";
    }
    try {      
      session = jsch.getSession(username, server, new Integer(port));
      session.setPassword(password);
      Properties prop = new Properties();
      // StrictHostKeyChecking:
      prop.setProperty("StrictHostKeyChecking", "no");
      // ask | yes | no
      session.setConfig(prop);
      // connect to sftp session
      session.connect();
      for (String remoteAbsoluteFile : fileSet) {
        if (stop) {
          break;
        }
        String fileName = remoteAbsoluteFile.substring(remoteAbsoluteFile.lastIndexOf("/") + 1);
        logger.info(">>>>>>>START TO SFTP TRANSFER :" + fileName);
        // create a .part file at local
        File currentFile = new File(workspaceDir + "/" + fileName);
        outStream = new FileOutputStream(currentFile);
        // open sftp channel
        cs = (ChannelSftp) session.openChannel("sftp");
        cs.connect();
        // support break point continue
        inStream = cs.get(remoteAbsoluteFile);
        byte[] buffer = new byte[1024];
        while (true) {
          // read file into buffer
          int bytesRead = inStream.read(buffer);
          if (bytesRead == -1) {
            break;
            // //if transfer is end, wait for 2000ms
            // Thread.sleep(2000);
            // //if original size of file is lower than transferedBytes, symbol file has done transfered
            // if(1 <= transferedBytes){
            // break;
            // }
          }
          // transferedBytes += bytesRead;
          // write content of buffer in output channel
          outStream.write(buffer, 0, bytesRead);
        }
        logger.info("SUCCESSFULY TRANSFER " + remoteAbsoluteFile);
        transferedFileNum++;
      }
    } catch (JSchException e) {
      logger.error("CAN'T CONNECT TO SFTP SERVER" + e);
      throw new FileTransferException(mc.getMessage(FileTransfer_MessageBundle.FileTransfer_Err_Fail2Conn));
    } catch (SftpException e) {
      logger.error("THE FILES WHICH WILL BE TRANSFER CAN NOT BE READ." + e);
      throw new FileTransferException(mc.getMessage(FileTransfer_MessageBundle.FileTransfer_Err_NoSuchFile));
    } catch (FileNotFoundException e) {
      logger.error(workspaceDir + " IS NOT EXIST", e);
      throw new FileTransferException(mc.getMessage(FileTransfer_MessageBundle.FileTransfer_Err_DestinationNotAvailable));
    } catch (Exception e) {
      logger.error("FAIL TO WRITE IN DESTINATION FILE", e);
      throw new FileTransferException("THERE IS THE PROBLEM WITH SFTP IMPORT");
    } finally {
      if (transferedFileNum==originalFileNum) {
        logger.info(">>>>>>>>>>DONE IMPORT ALL FILE!");
      }
      // disconnect sftp session
      stopImport();
      try {
        if (outStream != null){
          outStream.flush();
          // close output stream
          outStream.close();
        }
        // close sftp channel
      } catch (IOException e) {
        logger.error("FATAL TRANSPORT ERROR: " + e);
      }
    }
  }} --------------------编程问答-------------------- 哥们,有java使用SFTP上传文件例子吗?给发一份呗
补充:Java ,  Java相关
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,