我在通过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:超时:未建立套接字
我猜这是因为我在使用BindAddress
命令时没有设置带有-o
选项的shell。如果是这样,那么如何在JSch中设置-o BindAddress
参数?或者我做错了什么,请给我建议。
发布于 2014-10-25 15:15:02
我不认为在JSch中有明确的支持来选择要连接的网络接口。
但是您可以实现SocketFactory
接口,比如它使用constructor overload with the localAddr
创建Socket
实例
public Socket(InetAddress address, int port, InetAddress localAddr, int localPort)
(使用0表示localPort
)
然后在调用connect()
之前将工厂传递给Session.setSocketFactory()
,这样就可以了。
发布于 2014-10-25 17:29:04
我已经实现了解决方案,我在调用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-----
我是不是漏掉了什么,请提个建议...
发布于 2019-05-22 06:00:07
这将允许您绑定到特定的地址(和端口,需要这样做):
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()
之前设置了工厂
SocketFactory sfactory = new MySocketFactory();
session.setSocketFactory(sfactory);
session.connect();
https://stackoverflow.com/questions/26559957
复制相似问题