Java JSch SSH 隧道发送 HTTP 或 HTTPs 请求到远程服务器

标签 java http ssh jsch tcp

Java 程序员。我一直面临着使用 SSH 连接到服务器以从另一台服务器加载网页的任务。很快我就发现我对网络协议(protocol)的了解非常有限。首先,我尝试了动态端口转发 - 无济于事,它仅在商业图书馆中可用(而且所有这些都超出了我的经济能力)。然后我了解到使用 JSch,你实际上可以创建一个叫做直接 tcp-IP channel 的东西(我仍在尝试掌握这个概念),我在 stackoverflow 上找到了一些代码,应该用它来发送 HTTP使用 JSch 通过与另一台服务器的 SSH 连接向远程服务器发出请求。这是代码(从 TCP Connection over a secure ssh connection 的原始代码稍作修改)

    String host = "66.104.230.49";
    String user = "admin";
    String password = "default";
    int port = 22;

    String remoteHost = "souzpp.ru";
    int remotePort = 80;

    int localPort = 5001;
    int assignedPort;
    String localHost = "127.0.0.1";

    Properties config = new Properties();
    config.put("StrictHostKeyChecking", "no");

    try { 
        JSch jsch = new JSch();
        Session session = jsch.getSession(user, host, port);
        session.setPassword(password);
        session.setConfig(config);
        session.connect();
        assignedPort = session.setPortForwardingL(localPort, remoteHost, remotePort);
        Channel channel = session.openChannel("direct-tcpip");  

        System.out.println(assignedPort);
        ((ChannelDirectTCPIP)channel).setHost(localHost);
        ((ChannelDirectTCPIP)channel).setPort(assignedPort);

        String cmd = "GET /files/inst HTTP/1.0\r\n\r\n";

        InputStream in = channel.getInputStream();
        OutputStream out = channel.getOutputStream();

        channel.connect(10000);

        byte[] bytes = cmd.getBytes();          
        InputStream is = new ByteArrayInputStream(cmd.getBytes("UTF-8"));

        int numRead;

        while ((numRead = is.read(bytes)) >= 0)
              out.write(bytes, 0, numRead);

        out.flush();
        channel.disconnect();
        session.disconnect();

        System.out.println("Request supposed to have been sent");

        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            for (String line; (line = reader.readLine()) != null;){
                System.out.println(line);
            }
        } catch (java.io.IOException exc) {
            System.out.println(exc.toString());
        }

    } catch (Exception e){
        e.printStackTrace();
    }

此代码抛出以下异常:com.jcraft.jsch.JSchException: channel 未打开。 这里可能出了什么问题?拜托,如果答案与网络逻辑中的错误有关,而不是实现中的错误,如果您给我一个链接,其中包含有关我出错的任何有用信息,我将非常高兴。

(编辑:添加了 JavaCoderEx 建议的端口转发)

最佳答案

InputStream in = channel.getInputStream();
[...]
channel.disconnect();
session.disconnect();
[...]
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
for (String line; (line = reader.readLine()) != null;){

您正在关闭 TCP 流 channel ,然后关闭整个 SSH session ,然后尝试从 channel 读取数据。

在您真正完成之前不要关闭 SSH session 或 channel 。

关于Java JSch SSH 隧道发送 HTTP 或 HTTPs 请求到远程服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23768176/

相关文章:

http - "1970-01-01 00:00:00"过期 header

linux - 显示来自远程 linux 服务器的统计信息

networking - 亚马逊AWS VPC 场景2 : Specify the public IP address range of your network?

java - 使用可变成员变量构造 Test 对象的正确方法

java - Java 匿名类是在运行时创建的吗?

带有两个 "Transfer-Encoding: chunked" header 的 HTTP 响应

c# - MVC3 HttpStatusCodeResult 在 OnActionExecuted 中不起作用

java - SSH 输出始终为空

java - 从字符串创建 Java 日期,反之亦然

java - 等于方法覆盖问题