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

关于sftp连接的问题.

关于sftp连接的问题.2011-09-08 12:55最近在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的短连接,每次客户端发送一次请求, 服务端响应后关闭与客户端的连接. 如果客户端在服务端关闭连接后,没有释放连接,继续试图发送请求和接收响应. 这个时候就会出错. 

 

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

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

不知道有没别的问题,

请各位大侠求教了.

 
--------------------编程问答-------------------- 最近也在弄这个,网上的例子几乎都不可靠,几乎所有人都只关了连接而没有关session


   这一句 sshSession.connect();
    sshSession打开了为啥不知道关呢,应该先关session,再关sftp连接。正确的关法:
     if(sftp!=null){
       if(sftp.getSession()!=null){
           sftp.getSession().close;
       }
       sftp.disconnect();
    }
    你写得代码的正确性我就不做检查了,sftp默认端口号22,也可以改变 --------------------编程问答-------------------- 上面手动敲错了,抱歉应该是sftp.getSession().disconnect();知道意思就行了。可以写个定时任务不断的去连接,关闭,然后用netstat  -an 看看连接有没有释放 --------------------编程问答-------------------- 我又犯错了,应该先关sftp再关session吧,心里这么想的,一写出来就错
补充:Java ,  非技术区
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,