关于sftp连接的问题.

来源:互联网 发布:泛普软件 编辑:程序博客网 时间:2024/06/05 17:40

最近在window环境下弄了下sftp,用java代码写客户端的时候连接总是出问题.大家帮忙看下啊.

;

服务器端是配置在本地,上面是本地服务器的配置.

验证方式设置为密码验证,兼容密钥验证,为了简化程序下面使用的是密码验证.

用户名:userhash.

密码:1991

客户端代码是用jsch jar包工具实现.

代码如下:

package com.zj.sftp;

/*
* Created on 2011-9-7
* Copyright 2011 by zj
*
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Properties;
import java.util.Vector;

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.jcraft.jsch.UserInfo;

/**
* @author zhangjing
*/
public class MySFTP {
public static final UserInfo defaultUserInfo = new UserInfo() {
  public String getPassphrase() {
   return null;
  }

  public String getPassword() {
   return null;
  }

  public boolean promptPassword(String arg0) {
   return false;
  }

  public boolean promptPassphrase(String arg0) {
   return false;
  }

  public boolean promptYesNo(String arg0) {
   return true;
  }

  public void showMessage(String arg0) {
  }
};

/**
  * 连接sftp服务器
  *
  * @param host
  *            主机
  * @param port
  *            端口
  * @param username
  *            用户名
  * @param password
  *            密码
  * @return
  */
public ChannelSftp connect(String host, int port, String username,
   String password) {
  ChannelSftp sftp = null;
  try {
   JSch jsch = new JSch();
   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 + ".");

   // JSch jsch=new JSch();
   // Session session=jsch.getSession(username, host, port);
   // session.setPassword(password);
   // session.setUserInfo(defaultUserInfo);
   // session.connect();
   // Channel channel=session.openChannel("sftp");
   // channel.connect();
   // sftp=(ChannelSftp)channel;

  } catch (Exception e) {
   e.printStackTrace();
  }
  return sftp;
}

/**
  * 上传文件
  *
  * @param directory
  *            上传的目录
  * @param uploadFile
  *            要上传的文件
  * @param sftp
  */
public void upload(String directory, String uploadFile, ChannelSftp sftp) {
  try {
   sftp.cd(directory);
   File file = new File(uploadFile);
   sftp.put(new FileInputStream(file), file.getName());
  } catch (Exception e) {
   e.printStackTrace();
  }
}

/**
  * 下载文件
  *
  * @param directory
  *            下载目录
  * @param downloadFile
  *            下载的文件
  * @param saveFile
  *            存在本地的路径
  * @param sftp
  */
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();
  }
}

/**
  * 删除文件
  *
  * @param directory
  *            要删除文件所在目录
  * @param deleteFile
  *            要删除的文件
  * @param sftp
  */
public void delete(String directory, String deleteFile, ChannelSftp sftp) {
  try {
   sftp.cd(directory);
   sftp.rm(deleteFile);
  } catch (Exception e) {
   e.printStackTrace();
  }
}

/**
  * 列出目录下的文件
  *
  * @param directory
  *            要列出的目录
  * @param sftp
  * @return
  * @throws SftpException
  */
public Vector listFiles(String directory, ChannelSftp sftp)
   throws SftpException {
  return sftp.ls(directory);
}

public static void main(String[] args) {
  MySFTP sf = new MySFTP();
  String host = "127.0.0.1"; // 计算机名
  int port = 1314; // 端口号
  String username = "zhangjing"; // 用户名
  String password = "1991"; // 密码
  String directory = "/sftp"; // 读取文件的存放目录
  String uploadFile = "D:\\TGData\\keywords.txt"; // 要上传的文件
  // String downloadFile = "upload.txt"; //下载文件
  // String saveFile = "D:\\tmp\\download.txt";//保存文件路径,和文件名
  // String deleteFile = "delete.txt"; //要删除的文件名
  ChannelSftp sftp = sf.connect(host, port, username, password);
  sf.upload(directory, uploadFile, sftp); // 上传
  // sf.download(directory, downloadFile, saveFile, sftp); //下载
  // sf.delete(directory, deleteFile, sftp); //删除
  try {
   sftp.cd(directory);
   try {
    sftp.ls("/sftp"); // 首先查看下目录,如果不存在,系统会被错,捕获这个错,生成新的目录。
    System.out.println("存在目录");

   } catch (Exception e) {
    sftp.mkdir("/sftp");
    System.out.println("不存在目录,创建");
   }
   System.out.println("finished");
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   if (sftp != null) {
    sftp.disconnect();
    System.out.println("sftp is closed");
   } else if (sftp == null) {
    System.out.println("sftp is closed already");
   }
  }
}
}

本来这样是可以的.但是问题来了.在运行到ChannelSftp connect(String host, int port, String username, String password)方法中的sshSession.connect();方法时就报异常 java.net.SocketException: Software caused connection abort: recv failed.

网上查了下,原因可能是客户端和服务端建立tcp的短连接,每次客户端发送一次请求, 服务端响应后关闭与客户端的连接. 如果客户端在服务端关闭连接后,没有释放连接,继续试图发送请求和接收响应. 这个时候就会出错.

但是我和服务器端没有连接啊.不会出现没释放连接啊.

如果是代码的问题,上传也成功一次,但是仅仅一次.

不知道有没别的问题,

原创粉丝点击