首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用JSch连接到SFTP时如何选择网络接口

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

Stack Overflow用户
提问于 2014-10-25 14:40:50
回答 3查看 2.7K关注 0票数 3

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

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

代码语言:javascript
复制
sftp -o BindAddress=SOME_IP_ADDRRESS myUserName@HOST_IP_ADDR

它工作得很好,但是当我尝试使用Java (JSch)时,我得到了一个超时异常。Java代码是

代码语言:javascript
复制
/* 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:超时:未建立套接字

我猜这是因为我在使用BindAddress命令时没有设置带有-o选项的shell。如果是这样,那么如何在JSch中设置-o BindAddress参数?或者我做错了什么,请给我建议。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-10-25 15:15:02

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

但是您可以实现SocketFactory接口,比如它使用constructor overload with the localAddr创建Socket实例

代码语言:javascript
复制
public Socket(InetAddress address, int port, InetAddress localAddr, int localPort)

(使用0表示localPort)

然后在调用connect()之前将工厂传递给Session.setSocketFactory(),这样就可以了。

票数 3
EN

Stack Overflow用户

发布于 2014-10-25 17:29:04

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

代码语言:javascript
复制
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;
    }
});

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

代码语言:javascript
复制
logger.debug("socket created >> " + socket.toString());

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

身份验证取消

可能的原因是,我拥有的密钥是一个id_rsa.pub文件,它以

代码语言:javascript
复制
ssh-rsa AXTYU....

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

代码语言:javascript
复制
-----BEGIN RSA PRIVATE KEY-----
KIOPU.....
-----END RSA PRIVATE KEY-----

我是不是漏掉了什么,请提个建议...

票数 2
EN

Stack Overflow用户

发布于 2019-05-22 06:00:07

这将允许您绑定到特定的地址(和端口,需要这样做):

代码语言:javascript
复制
class MySocketFactory implements SocketFactory {

    @Override
    public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
        Socket socket = new Socket();
        socket.bind(new InetSocketAddress("1.1.1.1", 0));
        socket.connect(new InetSocketAddress(host, port));

        return socket;
    }

    @Override
    public InputStream getInputStream(Socket socket) throws IOException {
        return socket.getInputStream();
    }

    @Override
    public OutputStream getOutputStream(Socket socket) throws IOException {
        return socket.getOutputStream();
    }

}

我在我的Linux机器上使用netstat -an验证了这一点,并观察到连接的本地端使用临时端口号绑定到1.1.1.1 (我用这个地址临时设置了一个接口)。

我在调用session.connect()之前设置了工厂

代码语言:javascript
复制
SocketFactory sfactory = new MySocketFactory();
session.setSocketFactory(sfactory);

session.connect();
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26559957

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档