草庐IT

java - JSch:如何让 session 保持活跃

coder 2023-08-30 原文

我正在为使用 SSH 的静态路由管理编写 Java GUI 程序。我的代码如下:

import com.jcraft.jsch.*;
import java.io.*;

public class Konsep {
    String status;
    static String username;
    static String hostname;
    String inputcommand;
    String output;
    static Session session;

    JSch jsch = new JSch();

    public String status(String stringstatus) {
        stringstatus = status;
        return stringstatus;
    }

    public String InputCommand(String inputcommandstatus) {
        inputcommandstatus = inputcommand;
        return inputcommandstatus;
    }

    public void connect(String usernamelokal, String hostnamelokal,
            String password, int port) {
        //        JSch jsch=new JSch();
        try {
            Session sessionlokal = jsch.getSession(usernamelokal,
                    hostnamelokal, port);
            sessionlokal.setPassword(password);
            UserInfo ui = new UserInfoku.Infoku();
            sessionlokal.setUserInfo(ui);
            sessionlokal.setTimeout(0);
            sessionlokal.connect();
            status = "tersambung \n";
            username = usernamelokal;
            hostname = hostnamelokal;
            session = sessionlokal;
            System.out.println(username + " " + hostname);
        } catch (Exception e) {
            System.out.println(e);
            status = "Exception = \n " + e + "\n";

        }
    }

    public void disconnect() {
        //        JSch jsch=new JSch();
        try {
            Session sessionlokal = jsch.getSession(username, hostname);
            //            System.out.println(username +" "+ hostname);
            sessionlokal.disconnect();
            status = "wes pedhoott \n";
        } catch (Exception e) {
            System.out.println(e);
            status = "Exception = \n " + e + "\n";
        }

    }

    public void addRoute() {
        //        JSch jsch=new JSch();
        System.out.println(username + " " + hostname);
        try {
            Session sessionlokal = session; // =jsch.getSession(username, hostname);
            Channel channel = sessionlokal.openChannel("exec");
            ((ChannelExec) channel).setCommand(inputcommand);
            channel.setInputStream(null);
            channel.connect();
            ((ChannelExec) channel).setErrStream(System.err);
            InputStream in = channel.getInputStream();
            channel.connect();

            byte[] tmp = new byte[1024];
            while (true) {
                while (in.available() > 0) {
                    int i = in.read(tmp, 0, 1024);
                    if (i < 0)
                        break;
                    System.out.print(new String(tmp, 0, i));
                }
                if (channel.isClosed()) {
                    System.out.println("exit-status: "
                            + channel.getExitStatus());
                    break;
                }
                try {
                    Thread.sleep(1000);
                } catch (Exception ee) {
                }
            }

            channel.disconnect();
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}      

问题是当我调用connect方法然后调用addroute时,程序返回

root 192.168.50.2
root 192.168.50.2
com.jcraft.jsch.JSchException: session is down

我一直在尝试获取 session 状态

Session sessionlokal=session; //returns com.jcraft.jsch.JSchException: ChannelExec

Session sessionlokal=jsch.getSession(username, hostname); //returns session is down

我也尝试过使用 keepalive,但它也不起作用。

我的意图是创建一个 session 来主持(登录),同时让 session 保持运行状态,执行一个或多个命令,并可能稍后执行其他命令,然后在不需要时关闭 session (注销)。 我一直在这个论坛上搜索,我找到了这个 question但是代码是创建一个方法来定义一个命令先执行,然后创建 session ,调用命令的方法并关闭 session 。

关于如何按照我上面提到的去做有什么想法吗?

最佳答案

在尝试 Session.sendKeepAliveMsg() 没有成功之后,我得出了以下似乎相当稳定的解决方案:

private Session getSession() throws Exception {
    try {
        if (!session.isConnected()) {
            logger.info("Session successfully tested, use it again.");
            session.connect();
        }
    } catch (Throwable t) {
        logger.info("Session terminated. Create a new one.");
        session = jsch.getSession(user, host, port);
        session.setConfig(config);
        session.connect();
    }
    return session;
}

更新几天后它失败了。

我试图通过终止服务器上打开的 session 来测试它。我以这种方式测试的所有先前版本都显示出完全相同的行为,无论问题是在等待几天后弹出还是杀死服务器进程,所以我认为这个测试 - 以及上述解决方案的结果 - 是有意义的。不幸的是,事实并非如此。

我将尝试一些其他方法来修复它并让您了解最新信息。

更新 2:最终解决方案,保证不优雅且有效:

private Session getSession() throws Exception {
    try {
        ChannelExec testChannel = (ChannelExec) session.openChannel("exec");
        testChannel.setCommand("true");
        testChannel.connect();
        if(logger.isDebugEnabled()) {
            logger.debug("Session successfully tested, use it again.");
        }
        testChannel.exit();
    } catch (Throwable t) {
        logger.info("Session terminated. Create a new one.");
        session = jsch.getSession(user, host, port);
        session.setConfig(config);
        session.connect();
    }
    return session;
}

此版本在生产环境中运行数周。我每天记录一次信息消息。

打开一个 channel 和执行一些什么都不做的命令的成本有点烦人,但我发现没有其他方法可以确定 session 的状态。

关于java - JSch:如何让 session 保持活跃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16127200/

有关java - JSch:如何让 session 保持活跃的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  4. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  5. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  6. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  7. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  8. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  9. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  10. ruby - 如何使用文字标量样式在 YAML 中转储字符串? - 2

    我有一大串格式化数据(例如JSON),我想使用Psychinruby​​同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解

随机推荐