【问题标题】:How can I access an FTP server with JSch?如何使用 JSch 访问 FTP 服务器?
【发布时间】:2011-11-15 15:38:07
【问题描述】:

我在本地 Windows 7 机器上安装了 FileZilla FTP 服务器。 我还在同一台机器上安装了 FileZilla FTP 客户端。 两者之间的连接成功,确认服务器和客户端存在伙伴关系。

我编写了一个快速而肮脏的 Jsch 小程序,用于连接到 FileZilla FTP 服务器,下面是该程序:

public class TestJSch {

/** Creates a new instance of TestCommonsNet */
public TestJSch() {
}

/**
 * main - Unit test program
 * 
 * @param args
 *            Command line arguments
 * 
 */
public static void main(String[] args) {
    try {
        String ftpHost = "127.0.0.1";
        int ftpPort = 21;// 14147;
        // int ftpPort = 990;// 14147;
        String ftpUserName = "kedar";
        String ftpPassword = "XXXXXXXXXXX";
        String ftpRemoteDirectory = "C:\\KEDAR\\Java\\FTP_Folder";
        String fileToTransmit = "C:\\KEDAR\\Java\\File_Folder\\Customer.txt";
        String identityfile = "C:\\KEDAR\\Java\\Ftp\\certificate.crt";

        //
        // First Create a JSch session
        //
        JSch.setLogger(new MyLogger());
        System.out.println("Creating session.");

        JSch jsch = new JSch();

        String knownHostsFilename = "C:\\Windows\\System32\\drivers\\etc\\hosts";
        jsch.setKnownHosts(knownHostsFilename);
        jsch.addIdentity(identityfile);
        Session session = null;
        Channel channel = null;
        ChannelSftp c = null;

        //
        // Now connect and SFTP to the SFTP Server
        //
        try {
            // Create a session sending through our username and password
            session = jsch.getSession(ftpUserName, ftpHost, ftpPort);
            System.out.println("Session created.");
            session.setPassword(ftpPassword);
            // Security.addProvider(new com.sun.crypto.provider.SunJCE());

            // b
            // Setup Strict HostKeyChecking to no so we dont get the
            // unknown host key exception
            //
            java.util.Properties config = new java.util.Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
            session.connect();
            System.out.println("Session connected.");

            //
            // Open the SFTP channel
            //
            System.out.println("Opening Channel.");
            channel = session.openChannel("sftp");
            channel.connect();
            c = (ChannelSftp) channel;
        } catch (Exception e) {
            System.err.println("Unable to connect to FTP server."
                    + e.toString());
            throw e;
        }

        //
        // Change to the remote directory
        //
        System.out.println("Changing to FTP remote dir: "
                + ftpRemoteDirectory);
        c.cd(ftpRemoteDirectory);

        //
        // Send the file we generated
        //
        try {
            File f = new File(fileToTransmit);
            System.out.println("Storing file as remote filename: "
                    + f.getName());
            c.put(new FileInputStream(f), f.getName());
        } catch (Exception e) {
            System.err
                    .println("Storing remote file failed." + e.toString());
            throw e;
        }   

        //
        // Disconnect from the FTP server
        //
        try {
            c.quit();
        } catch (Exception exc) {
            System.err.println("Unable to disconnect from FTPserver. "
                    + exc.toString());
        }

    } catch (Exception e) {
        System.err.println("Error: " + e.toString());
    }

    System.out.println("Process Complete.");
    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);
    }
}
}

我试过运行这个程序,下面是 FTP 日志:

(000033)9/12/2011 13:08:53 PM -(未登录)(127.0.0.1)> 已连接,正在发送欢迎消息...
(000033)9/12/2011 13:08:53 PM -(未登录)(127.0.0.1)> 220-FileZilla 服务器版本 0.9.39 beta
(000033)9/12/2011 13:08:53 PM -(未登录)(127.0.0.1)> 220-由 Tim Kosse (Tim.Kosse@gmx.de) 编写
(000033)9/12/2011 13:08:53 PM - (未登录) (127.0.0.1)> 220 请访问​​http://sourceforge.net/projects/filezilla/
(000033)9/12/2011 13:08:53 PM -(未登录)(127.0.0.1)> SSH-2.0-JSCH-0.1.44
(000033)9/12/2011 13:08:53 PM -(未登录)(127.0.0.1)> 500 语法错误,命令无法识别。
(000033)9/12/2011 13:09:54 PM -(未登录)(127.0.0.1)> 421 登录时间已过。关闭控制连接。
(000033)9/12/2011 13:09:54 PM -(未登录)(127.0.0.1)> 已断开连接。

我不明白为什么 JSch 程序发出SSH-2.0-JSCH-0.1.44 命令,然后通信被拒绝。我们如何避免这种情况?

【问题讨论】:

    标签: java ftp sftp jsch


    【解决方案1】:

    JSch 不是 FTP 客户端。 JSch 是 SSH 客户端(包含 SFTP 实现)。

    SSH 协议是一种允许安全连接到服务器的协议,用于外壳访问、文件传输或端口转发。为此,服务器必须有一个 SSH 服务器(通常在端口 22 上,但可能会有所不同)。 SFTP 是一种二进制文件传输协议,通常通过 SSH 进行隧道传输,与 FTP 无关(名称除外)。

    如果您想使用 JSch 下载/上传文件,您需要在您的计算机上安装并激活一个 SSH/SFTP 服务器(无论您要访问哪台计算机)。

    对于 FTP,您必须使用其他 Java 库(Apache Commons FTPClient 似乎很有名,从这里的问题来看)。

    顺便说一下,JSch 的 known hosts 文件是一个列出 SSH 主机的公钥的文件,而不是列出它们的 IP 地址的文件(这是您尝试使用的 Windows 配置文件)在这里提供)。

    【讨论】:

      【解决方案2】:

      使用Apache commons-net FTP library

      import java.io.IOException;
      
      import org.apache.commons.net.ftp.FTPClient;
      
      import org.apache.commons.net.ftp.FTPReply;
      
      public class FTPConnectionCode {
      
          public static void main(String[] args) {
              String server = "www.website.com";
             // generally ftp port is 21
              int port = 21;
              String user = "ftpusername";
              String pass = "ftppassword";
      
              FTPClient ftpClient = new FTPClient();
      
              try {
      
                  ftpClient.connect(server, port);
                  showServerReply(ftpClient);
      
                  int replyCode = ftpClient.getReplyCode();
                  if (!FTPReply.isPositiveCompletion(replyCode)) {
                      System.out.println("Connect failed");
                      return;
                  }
      
                  boolean success = ftpClient.login(user, pass);
                  showServerReply(ftpClient);
      
                  if (!success) {
                      System.out.println("Could not login to the server");
                      return;
                  }
      
                  // Changes working directory
                  success = ftpClient.changeWorkingDirectory("/dir");
                  showServerReply(ftpClient);
      
                  if (success) {
                      System.out.println("Successfully changed working directory.");
                  } else {
                      System.out.println("Failed to change working directory. See server's reply.");
                  }
      
                  // logs out
                  ftpClient.logout();
                  ftpClient.disconnect();
      
              } catch (IOException ex) {
                  System.out.println("Oops! Something wrong happened");
                  ex.printStackTrace();
              }
          }
      
          private static void showServerReply(FTPClient ftpClient) {
              String[] replies = ftpClient.getReplyStrings();
              if (replies != null && replies.length > 0) {
                  for (String aReply : replies) {
                      System.out.println("SERVER: " + aReply);
                  }
              }
          }
      }
      

      【讨论】:

      • 为了避免链接失效时信息丢失,链接页面中相关信息的引用比简单的链接要好得多。
      猜你喜欢
      • 1970-01-01
      • 2021-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 2014-10-29
      • 2018-10-21
      相关资源
      最近更新 更多