2013-01-14 15 views
13

Ben bu basit örnekten şey yapmaya çalışıyorum bağlantı:Basit SSH JSch

SSH, execute remote commands with Android

Sadece SSH kullanarak bir linux sunucuya benim android telefondan bağlanabilir görmek istiyorum

ama o değil çalışamam ... İşte

benim ana kod edilir:

package com.example.ssh; 

import java.util.Properties; 
import com.jcraft.jsch.JSch; 
import com.jcraft.jsch.Session; 
import android.os.Bundle; 
import android.app.Activity; 

public class MainActivity extends Activity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    try 
    { 
     JSch jsch = new JSch(); 
      Session session = jsch.getSession("root","192.168.0.26", 22); 
      session.setPassword("xxxxx"); 

      // Avoid asking for key confirmation 
      Properties prop = new Properties(); 
      prop.put("StrictHostKeyChecking", "no"); 
      session.setConfig(prop); 

      session.connect(); 

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

ben yanlış yaptım

? Hata mesajım yok ve Linux'umda herhangi bir SSH bağlantısı görmüyorum. Jsch ve jzlib kütüphanelerini ekledim. Bir macun oturumuyla bağlantı kurmak için hiçbir problemim yok.

EDIT1: Aslında, sorunu nasıl çözeceğimi bilmesem bile neden çalışmadığını açıklayan bir hata buldum. Hata şudur: bu kodu çalıştırmak zorunda böylece Uygulamanın ana iş parçacığı üzerinde bir ağ işlemi gerçekleştiremiyor anlamına görünüyor

...

cevap

16

android.os.NetworkOnMainThreadException Başka bir iş parçacığı, UI iş parçacığı askıda kalmaz, bu özel durumun anlamıdır. Kullanıcı Arayüzü iş parçacığı bir ağ çağrısı yürütüyorsa, kullanıcı arabirimini yeniden çizemez, böylece kullanıcılar ağ görüşmesinin bitmesini beklerken yanıt vermeyen bir kullanıcı arayüzü görür. Android, bu gibi kötü kullanıcı deneyimlerinden kaçınmak istemektedir, bu nedenle bu istisnayı atarak böyle şeyler yapmanı engellemektedir.

OnCreate() yönteminiz, SSH bağlantısını gerçekleştirmek için başka bir iş parçacığı (işlenmemiş bir iş parçacığı üzerinde bir AsyncTask kullanmayı öneririm) çağırmalıdır. Daha sonra bittiğinde sonuçları UI iş parçacığına geri gönderebilir ve uygulamanızın kullanıcı arayüzünü kullanıcı arabiriminden güvenli bir şekilde güncelleyebilir.

http://developer.android.com/reference/android/os/AsyncTask.html

+0

Sadece hızlı bir çözüm isteyenler için de bu sorun için yapılan kod paylaşmak istiyorum Teşekkürler ! Ben senin çözümünü deneyeceğim. – Pozinux

12

chubbsondubs çözümü mükemmeldir.

public class MainActivity extends Activity { 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    new AsyncTask<Integer, Void, Void>(){ 
     @Override 
     protected Void doInBackground(Integer... params) { 
      try { 
       executeRemoteCommand("root", "myPW","192.168.0.26", 22); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
      return null; 
     } 
    }.execute(1); 
} 

public static String executeRemoteCommand(String username,String password,String hostname,int port) 
     throws Exception { 
    JSch jsch = new JSch(); 
    Session session = jsch.getSession(username, hostname, port); 
    session.setPassword(password); 

    // Avoid asking for key confirmation 
    Properties prop = new Properties(); 
    prop.put("StrictHostKeyChecking", "no"); 
    session.setConfig(prop); 

    session.connect(); 

    // SSH Channel 
    ChannelExec channelssh = (ChannelExec) 
      session.openChannel("exec"); 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    channelssh.setOutputStream(baos); 

    // Execute command 
    channelssh.setCommand("lsusb > /home/pi/test.txt"); 
    channelssh.connect(); 
    channelssh.disconnect(); 

    return baos.toString(); 
} 
0

A Kotlin çözüm:

import android.os.AsyncTask 
import android.os.Bundle 
import android.support.v7.app.AppCompatActivity 
import com.jcraft.jsch.ChannelExec 
import com.jcraft.jsch.JSch 
import java.io.ByteArrayOutputStream 
import java.util.* 

class MainActivity : AppCompatActivity() { 
    override fun onCreate(savedInstanceState: Bundle?) { 
     super.onCreate(savedInstanceState) 
     setContentView(R.layout.activity_main) 
     SshTask().execute() 
    } 

    class SshTask : AsyncTask<Void, Void, String>() { 
     override fun doInBackground(vararg p0: Void?): String { 
      val output = executeRemoteCommand("demo", "password", "test.rebex.net") 
      print(output) 
      return output 
     } 
    } 
} 

fun executeRemoteCommand(username: String, 
         password: String, 
         hostname: String, 
         port: Int = 22): String { 
    val jsch = JSch() 
    val session = jsch.getSession(username, hostname, port) 
    session.setPassword(password) 

    // Avoid asking for key confirmation. 
    val properties = Properties() 
    properties.put("StrictHostKeyChecking", "no") 
    session.setConfig(properties) 

    session.connect() 

    // Create SSH Channel. 
    val sshChannel = session.openChannel("exec") as ChannelExec 
    val outputStream = ByteArrayOutputStream() 
    sshChannel.outputStream = outputStream 

    // Execute command. 
    sshChannel.setCommand("ls") 
    sshChannel.connect() 

    // Sleep needed in order to wait long enough to get result back. 
    Thread.sleep(1_000) 
    sshChannel.disconnect() 

    session.disconnect() 

    return outputStream.toString() 
} 

build.gradle eklenti olarak:

dependencies { 
    ... 
    compile group: 'com.jcraft', name: 'jsch', version: '0.1.54' 
}