0

We are deploying a Java project on Linux Server. A file is generated by the project which is then sent to a remote server.

It was earlier implemented using Jsch. However, due to its dependency on JCE and the inability to upgrade the java version (from 5) we are switching to Ganymed. I am using Ganymed build 210 (viz. is tested for java 5; http://www.ganymed.ethz.ch/ssh2)

This is the function I am using to sftp the file.

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;
}

I am unable to connect to the remote server possibly due to binding issues and unsure on how to proceed? I am thinking on binding a local address before the SFTP.

So I wrote a socket function.

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;
}

However this is also not working, and I am getting a Socket Exception.

EDIT: So I was creating the socket in the right way but no where am I using the same socket for creating the connection. Such a method is not defined in any of the Ganymed libraries.

4

1 回答 1

1

由于 ganymed 中没有固有的方法,所以我编辑源代码编写了一个方法。

以下是我所做的编辑。

到我正在使用的班级

SocketAddress sourceAddress = new InetSocketAddress(bindAddress,
                bindPort);
        Connection ssh = new Connection(host, port);
        ssh.bindSourceAddress(sourceAddress);
        ssh.connect();

然后我对 Ganymed API 的 connection.class 进行了一些更改。相应地导入类和声明的变量

这是传递 bindAddress 的简单方法。

public void bindSourceAddress(SocketAddress sourceAddress) {
            this.sourceAddress = sourceAddress;
        }

使用初始化方法时将地址传递给传输管理器类。

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 新手,我花了我自己的甜蜜时间来做到这一点。没有人很可能会阅读或需要它,但发布此解决方案以防万一像我这样的人!

于 2016-01-15T05:47:30.387 回答