【问题标题】:How to reuse a SSH (Jsch) session created in an AsyncTask in another class如何在另一个类中重用在 AsyncTask 中创建的 SSH (Jsch) 会话
【发布时间】:2014-11-19 05:30:42
【问题描述】:

我是 Android 和 Java 新手,我的情况如下:

我正在尝试创建一个应用程序,该应用程序使用 ssh 连接连接到 Beaglebone Black,然后通过发出来自 Android 设备的命令来控制连接到 BBB 的一些外围设备。 当用户看到启动屏幕时,我在 AsyncTask 中打开(成功)一个 ssh 会话,如果连接成功,用户将获得确认,然后将能够通过单击一些可用按钮发送预定义的命令。

接下来我要做的是让会话保持打开状态,然后每次我希望发出命令并等待 BBB 的响应时创建一个新通道(exec 或 shell),但我不知道如何在 AsynkTask 之外重用此类 ssh 会话。

这可能吗?

我使用的是Android Studio 0.8.2和Jsch 0.1.51,我的代码如下:

公共类 SplashScreen 扩展 ActionBarActivity {

public static final int segundos =10;
public static final int milisegundos =segundos*1000;
public static  final int delay=2;
private ProgressBar pbprogreso;
@Override

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_splash_screen);
    pbprogreso= (ProgressBar)findViewById(R.id.pbprogreso);
    pbprogreso.setMax(maximo_progreso());
    empezaranimacion();
}

public void empezaranimacion()
{
    sshConnect task = new sshConnect();
    task.execute(new String[] {"http:"});

    new CountDownTimer(milisegundos,1000)

    {
        @Override
    public void onTick(long milisUntilFinished){
            pbprogreso.setProgress(establecer_progreso(milisUntilFinished));
        }
       @Override
    public void onFinish(){
           finish();
       }
    }.start();

}
public  int establecer_progreso (long miliseconds)
{
    return (int)((milisegundos-miliseconds)/1000);
}

public int maximo_progreso () {
    return segundos-delay;
}

public class sshConnect extends AsyncTask <String, Void, String>{
    ByteArrayOutputStream Baos=new ByteArrayOutputStream();
    ByteArrayInputStream Bais = new ByteArrayInputStream(new byte[1000]);
    @Override
    protected String doInBackground(String... data) {

        String host = "xxxxxxx";
        String user = "root";
        String pwd = "";
        int port = 22;
        JSch jsch = new JSch();
        try {
            Session session = jsch.getSession(user, host, port);
            session.setPassword(pwd);
            session.setConfig("StrictHostKeyChecking", "no");
            session.connect();

            ChannelExec channel = (ChannelExec)session.openChannel("exec");
            channel.setOutputStream(Baos);
            channel.setInputStream(Bais);
            //Run Command
            channel.setCommand("python ~/BBB_test/testconnect.py");
            channel.connect();
            try{Thread.sleep(3500);}catch (Exception ee){}
            channel.disconnect();
            //session.disconnect();
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
        return Baos.toString();
    }
    @Override
    protected void onPostExecute(String result) {
        if (result.equals("Connected to BBB Baby!!\n")) {
            Intent nuevofrom = new Intent(SplashScreen.this, Principal.class);
            startActivity(nuevofrom);
            finish();
        } else {
            Intent newfrom = new Intent(SplashScreen.this, ConnecError.class);
            startActivity(newfrom);
            finish();

        }
    }
}

//这里是我想重用打开的会话并创建一个新频道的地方

public class sendCommand extends AsyncTask <String, Void, String >{
    ByteArrayOutputStream Baosc=new ByteArrayOutputStream();
    ByteArrayInputStream Baisc = new ByteArrayInputStream(new byte[1000])

    protected String doInBackground (String... command){
        try {
            ChannelExec channel2 = (ChannelExec)session.openChannel("exec");
            channel2.setOutputStream(Baosc);
            channel2.setInputStream(Baisc);
            //Run Command
            channel2.setCommand("python ~/BBB_test/testgpio.py");
            channel2.connect();
            try{Thread.sleep(3500);}catch (Exception ee){}
            channel2.disconnect();


        }catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return  Baosc.toString();
    }
    protected void onPostExecute(Long result) {
        TextView txt = (TextView) findViewById(R.id.infotext);
        txt.setText(result);

    }

}

如果需要其他东西,请告诉我! (这是我第一次在论坛上提问)

非常感谢您的时间和支持!

【问题讨论】:

    标签: session android-asynctask jsch


    【解决方案1】:

    如果你想重用会话,你不需要每次都重新连接通道。将其作为外壳连接一次,将输入和输出流插入其中。使用流来传递命令和捕获输出。

    See the JSCH example on the JCraft website.

      Channel channel=session.openChannel("shell");
    
      channel.setInputStream(System.in);
      channel.setOutputStream(System.out);
    
      channel.connect();
    

    【讨论】:

    • 谢谢@Damienknight,我也在考虑这个问题,我怎么能“调用”我在“doInBackgroud”方法上打开的会话?
    • 在 doInBackground 之外创建会话,并在调用 doInBackground 时传递会话。从会话对象中,您可以检索通道、输入/输出流等。
    • 我想我明白你的意思了,我去试试,
    【解决方案2】:

    通过使用 DamienKnight 的建议,在 Asynktask 类之外创建会话,我设法得到了我想要的东西。我创建了一个公共类,使用三种方法来创建、返回和断开会话:

    public static class cSession {
            String host = "xxx.xxx.xxx.xxx";
            String user = "root";
            String pwd = "";
            int port = 22;
            JSch jsch = new JSch();
            public Session Met1 (){
                try {
                    session = jsch.getSession(user, host, port);
                    session.setPassword(pwd);
                    session.setConfig("StrictHostKeyChecking", "no");
                } catch (Exception e2){
                    System.out.println(e2.getMessage());
                }return session;
            }
            public Session damesession (){
                return session;
            }
            public void close_ses(){
                session.disconnect();
            }
        }
    

    这样做,通道的创建很灵活,我也可以使用 Jsch 的方法。

    public class sshConnect extends AsyncTask <String, Void, String>{
            ByteArrayOutputStream Baos=new ByteArrayOutputStream();
            ByteArrayInputStream Bais = new ByteArrayInputStream(new byte[1000]);
    
    
            @Override
            protected String doInBackground(String... data) {
                cSession jschses = new cSession();
                Session ses =null;
                ses = jschses.Met1();
                try {
                    ses.connect();
                    ChannelExec channel = (ChannelExec)ses.openChannel("exec");
                    channel.setOutputStream(Baos);
                    channel.setInputStream(Bais);
                    //Run Command
                    channel.setCommand("python ~/BBB_test/testconnect.py");
                    channel.connect();
                    try{Thread.sleep(3500);}catch (Exception ee){}
                    channel.disconnect();
                    //session.disconnect();
                }catch (Exception e){
                    System.out.println(e.getMessage());
                }
                return Baos.toString();
    
            }
    

    感谢@Damienknight!

    问候

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-01
      • 1970-01-01
      • 2021-09-30
      • 1970-01-01
      • 1970-01-01
      • 2012-03-08
      • 2015-01-04
      相关资源
      最近更新 更多