如何在使用 Ganymed API 到 SFTP 时将本地地址绑定为源地址?
How to bind a local address as the source address while using Ganymed API to SFTP?
我们正在 Linux 服务器上部署 Java 项目。项目生成一个文件,然后将其发送到远程服务器。
它之前是使用 Jsch 实现的。然而,由于它依赖于 JCE 并且无法升级 java 版本(从 5),我们正在切换到 Ganymed。我正在使用 Ganymed build 210(即针对 java 5;http://www.ganymed.ethz.ch/ssh2)
进行了测试
这是我用来 sftp 文件的函数。
public boolean sftp_put() {
File privateKeyFile = new File(identityPath);
File rfile = new File(hostDir);
File lfile = new File(lpath);
boolean success = false;
try {
if (!lfile.exists() || lfile.isDirectory()) {
throw new IOException("Local file must be a regular file: "
+ lpath);
}
Connection ssh = new Connection(host, port);
ssh.connect();
ssh.authenticateWithPublicKey(user, privateKeyFile, password);
SFTPv3Client sftp = new SFTPv3Client(ssh);
try {
SFTPv3FileAttributes attr = sftp.lstat(hostDir);
if (attr.isDirectory()) {
rfile = new File(hostDir, lfile.getName());
}
} catch (SFTPException e) {
try {
SFTPv3FileAttributes attr = sftp.lstat(rfile.getParent());
if (!attr.isDirectory()) {
throw new IOException(
"Remote file's parent must be a directory: "
+ hostDir + "," + e);
}
} catch (SFTPException ex) {
throw new IOException(
"Remote file's parent directory must exist: "
+ hostDir + "," + ex);
}
}
SFTPv3FileHandle file = sftp.createFileTruncate(rfile
.getCanonicalPath());
long fileOffset = 0;
byte[] src = new byte[32768];
int i = 0;
FileInputStream input = new FileInputStream(lfile);
while ((i = input.read(src)) != -1) {
sftp.write(file, fileOffset, src, 0, i);
fileOffset += i;
}
input.close();
sftp.closeFile(file);
sftp.close();
success=true;
} catch (IOException e1) {
logger.warn("Exception while trying to sftp", e)
}
return success;
}
我可能由于绑定问题而无法连接到远程服务器并且不确定如何继续?我正在考虑在 SFTP 之前绑定一个本地地址。
所以我写了一个socket函数
public Socket createSocket(String destinationHost, int destinationPort)
throws IOException, UnknownHostException {
logger.info("sftp configured bind address : " + bindAddress
+ ", bind port : " + bindPort);
Socket socket = new Socket();
socket.bind(new InetSocketAddress(bindAddress, bindPort));
socket.connect(new InetSocketAddress(destinationHost, destinationPort),
connectionTimeOut);
if (socket.isBound()) {
logger.info("sftp actual bind port : " + socket.getLocalPort());
} else {
logger.warn("sftp socket not bound to local port");
}
return socket;
}
但是这也不起作用,我得到了套接字异常。
编辑:所以我以正确的方式创建了套接字,但不知道我在哪里使用相同的套接字来创建连接。这种方法在任何 Ganymed 库中都没有定义。
由于ganymed中没有固有方法,所以我编辑了源代码写了一个方法。
以下是我所做的编辑。
到我正在使用
的 class
SocketAddress sourceAddress = new InetSocketAddress(bindAddress,
bindPort);
Connection ssh = new Connection(host, port);
ssh.bindSourceAddress(sourceAddress);
ssh.connect();
然后我对 Ganymed API 的 connection.class 做了一些修改。导入 class 并相应地声明变量
这是传递绑定地址的简单方法。
public void bindSourceAddress(SocketAddress sourceAddress) {
this.sourceAddress = sourceAddress;
}
使用初始化方法时将地址传递给传输管理器class。
if (sourceAddress != null) {
tm.initialize(cryptoWishList, verifier, dhgexpara,
connectTimeout, getOrCreateSecureRND(), proxyData,
sourceAddress);
} else {
tm.initialize(cryptoWishList, verifier, dhgexpara,
connectTimeout, getOrCreateSecureRND(), proxyData);
}
修改了initialize方法的构造函数。它依次调用建立连接函数,该函数经过类似修改以适应 SocketAddress。
private void establishConnection(ProxyData proxyData, int connectTimeout, SocketAddress sourceAddress) throws IOException
{
/* See the comment for createInetAddress() */
if (proxyData == null)
{
InetAddress addr = createInetAddress(hostname);
//test
if (sourceAddress != null) {
sock.bind(sourceAddress);
}
sock.connect(new InetSocketAddress(addr, port), connectTimeout);
sock.setSoTimeout(0);
return;
}
if (proxyData instanceof HTTPProxyData)
{
HTTPProxyData pd = (HTTPProxyData) proxyData;
/* At the moment, we only support HTTP proxies */
InetAddress addr = createInetAddress(pd.proxyHost);
//test
if (sourceAddress != null) {
sock.bind(sourceAddress);
}
sock.connect(new InetSocketAddress(addr, pd.proxyPort), connectTimeout);
sock.setSoTimeout(0);
终于绑定了socket。作为一个 java 新手,我花了我自己的甜蜜时间来做对。很可能没有人会阅读或需要它,但发布此解决方案以防万一像我这样的人!
我们正在 Linux 服务器上部署 Java 项目。项目生成一个文件,然后将其发送到远程服务器。
它之前是使用 Jsch 实现的。然而,由于它依赖于 JCE 并且无法升级 java 版本(从 5),我们正在切换到 Ganymed。我正在使用 Ganymed build 210(即针对 java 5;http://www.ganymed.ethz.ch/ssh2)
进行了测试这是我用来 sftp 文件的函数。
public boolean sftp_put() {
File privateKeyFile = new File(identityPath);
File rfile = new File(hostDir);
File lfile = new File(lpath);
boolean success = false;
try {
if (!lfile.exists() || lfile.isDirectory()) {
throw new IOException("Local file must be a regular file: "
+ lpath);
}
Connection ssh = new Connection(host, port);
ssh.connect();
ssh.authenticateWithPublicKey(user, privateKeyFile, password);
SFTPv3Client sftp = new SFTPv3Client(ssh);
try {
SFTPv3FileAttributes attr = sftp.lstat(hostDir);
if (attr.isDirectory()) {
rfile = new File(hostDir, lfile.getName());
}
} catch (SFTPException e) {
try {
SFTPv3FileAttributes attr = sftp.lstat(rfile.getParent());
if (!attr.isDirectory()) {
throw new IOException(
"Remote file's parent must be a directory: "
+ hostDir + "," + e);
}
} catch (SFTPException ex) {
throw new IOException(
"Remote file's parent directory must exist: "
+ hostDir + "," + ex);
}
}
SFTPv3FileHandle file = sftp.createFileTruncate(rfile
.getCanonicalPath());
long fileOffset = 0;
byte[] src = new byte[32768];
int i = 0;
FileInputStream input = new FileInputStream(lfile);
while ((i = input.read(src)) != -1) {
sftp.write(file, fileOffset, src, 0, i);
fileOffset += i;
}
input.close();
sftp.closeFile(file);
sftp.close();
success=true;
} catch (IOException e1) {
logger.warn("Exception while trying to sftp", e)
}
return success;
}
我可能由于绑定问题而无法连接到远程服务器并且不确定如何继续?我正在考虑在 SFTP 之前绑定一个本地地址。
所以我写了一个socket函数
public Socket createSocket(String destinationHost, int destinationPort)
throws IOException, UnknownHostException {
logger.info("sftp configured bind address : " + bindAddress
+ ", bind port : " + bindPort);
Socket socket = new Socket();
socket.bind(new InetSocketAddress(bindAddress, bindPort));
socket.connect(new InetSocketAddress(destinationHost, destinationPort),
connectionTimeOut);
if (socket.isBound()) {
logger.info("sftp actual bind port : " + socket.getLocalPort());
} else {
logger.warn("sftp socket not bound to local port");
}
return socket;
}
但是这也不起作用,我得到了套接字异常。
编辑:所以我以正确的方式创建了套接字,但不知道我在哪里使用相同的套接字来创建连接。这种方法在任何 Ganymed 库中都没有定义。
由于ganymed中没有固有方法,所以我编辑了源代码写了一个方法。
以下是我所做的编辑。
到我正在使用
的 classSocketAddress sourceAddress = new InetSocketAddress(bindAddress,
bindPort);
Connection ssh = new Connection(host, port);
ssh.bindSourceAddress(sourceAddress);
ssh.connect();
然后我对 Ganymed API 的 connection.class 做了一些修改。导入 class 并相应地声明变量
这是传递绑定地址的简单方法。
public void bindSourceAddress(SocketAddress sourceAddress) {
this.sourceAddress = sourceAddress;
}
使用初始化方法时将地址传递给传输管理器class。
if (sourceAddress != null) {
tm.initialize(cryptoWishList, verifier, dhgexpara,
connectTimeout, getOrCreateSecureRND(), proxyData,
sourceAddress);
} else {
tm.initialize(cryptoWishList, verifier, dhgexpara,
connectTimeout, getOrCreateSecureRND(), proxyData);
}
修改了initialize方法的构造函数。它依次调用建立连接函数,该函数经过类似修改以适应 SocketAddress。
private void establishConnection(ProxyData proxyData, int connectTimeout, SocketAddress sourceAddress) throws IOException
{
/* See the comment for createInetAddress() */
if (proxyData == null)
{
InetAddress addr = createInetAddress(hostname);
//test
if (sourceAddress != null) {
sock.bind(sourceAddress);
}
sock.connect(new InetSocketAddress(addr, port), connectTimeout);
sock.setSoTimeout(0);
return;
}
if (proxyData instanceof HTTPProxyData)
{
HTTPProxyData pd = (HTTPProxyData) proxyData;
/* At the moment, we only support HTTP proxies */
InetAddress addr = createInetAddress(pd.proxyHost);
//test
if (sourceAddress != null) {
sock.bind(sourceAddress);
}
sock.connect(new InetSocketAddress(addr, pd.proxyPort), connectTimeout);
sock.setSoTimeout(0);
终于绑定了socket。作为一个 java 新手,我花了我自己的甜蜜时间来做对。很可能没有人会阅读或需要它,但发布此解决方案以防万一像我这样的人!