使用JSch连接SFTP时如何选择网络接口

时间:2014-10-25 06:40:50

标签: java bind sftp jsch

我遇到了通过JSch创建远程SFTP服务器会话的问题:

我用来通过shell连接sftp服务器的命令是:

sftp -o BindAddress=SOME_IP_ADDRRESS myUserName@HOST_IP_ADDR

并且它工作正常,但是当我尝试使用Java(JSch)时,我收到了超时异常。 Java代码是

/* KEY_FILE_NAME = is a file with rsa public key */
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource(KEY_FILE_NAME).getFile());
JSch jsch = new JSch();
jsch.addIdentity(file.getAbsolutePath());
Properties hash = new Properties();
hash.put("StrictHostKeyChecking", "no");
logger.debug("SSh Server Host name >>" + SSH_SERVER_HOST_NAME + " || User Name >>" +  SSH_SERVER_USER_NAME);

session = jsch.getSession(SSH_SERVER_USER_NAME, SSH_SERVER_HOST_NAME);
UserInfo ui = new MyUserInfo();
session.setUserInfo(ui);
session.setConfig(hash);
session.setPort(22);
session.setTimeout(45000);
session.connect();

我得到的例外是:

  

com.jcraft.jsch.JSchException:timeout:socket未建立

我想它会在我使用shell命令时设置BindAddress并使用-o选项。如果是这种情况,那么如何在JSch中设置-o BindAddress参数?或者我做错了什么,请建议。

3 个答案:

答案 0 :(得分:3)

我认为没有明确支持在JSch中选择要连接的网络接口。

但您可以实现SocketFactory界面,例如使用constructor overload with the localAddr创建Socket实例:

public Socket(InetAddress address, int port, InetAddress localAddr, int localPort)

(对localPort使用0)

然后将工厂传递给Session.setSocketFactory(),然后再致电connect(),你就应该做得很好。

答案 1 :(得分:2)

我已经实现了解决方案,我在调用session.connect()之前添加了以下代码。

session.setSocketFactory(new SocketFactory() 
{
    InputStream in = null;
    OutputStream out = null;

    public InputStream getInputStream(Socket socket) throws IOException 
    {
        if (in == null)
            in = socket.getInputStream();
        return in;
    }

    public OutputStream getOutputStream(Socket socket) throws IOException 
    {
        if (out == null)
            out = socket.getOutputStream();
        return out;
    }

    public Socket createSocket(String host, int port) throws IOException, UnknownHostException 
    {
       // The IP Addresses are changed ....
       // using the original IP in my code
        byte[] remoteIpAddr = new byte[] { (byte) 11,(byte) 11, 11, 11 }; 
        byte[] localIpAddr = new byte[] { 55, 55, 55, 55 };

        InetAddress remoteIp = InetAddress.getByAddress(remoteIpAddr);
        InetAddress localIp = InetAddress.getByAddress(localIpAddr);

        logger.debug("remoteIp >>" + remoteIp.toString());
        logger.debug("localIp >>" + localIp.toString());
        Socket socket = new Socket(remoteIp, 22, localIp, 0);
        logger.debug("socket created >> " + socket.toString());
        return socket;
    }
});

创建套接字:检查日志文件>>

logger.debug("socket created >> " + socket.toString());

但现在我得到了一个例外:

验证取消

可能是什么原因,我的关键是 id_rsa.pub 文件,该文件以

开头
ssh-rsa AXTYU....

我已经通过我在session.addIdentity()方法中使用的keygen从此文件创建了私钥文件,私钥的格式为:

-----BEGIN RSA PRIVATE KEY-----
KIOPU.....
-----END RSA PRIVATE KEY-----

我错过了什么,请建议......

答案 2 :(得分:0)

这将使您可以绑定到特定地址(和端口,应绑定):https://stackoverflow.com/a/56120718/11173046