Android 实现Telnet终端

来源:互联网 发布:2017中国人工智能排名 编辑:程序博客网 时间:2024/06/02 01:38
    最近项目有个需求,需要在APP端实现Telnet操作。本来网上Telnet手机终端相关的APP,但是和公司的要求有点不符合,所以只能苦逼的自己写啦。废话不说了,直接进入主题。
    Telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准协议和主要方式。它为用户提供了在本地计算机上完成远程主机工作的能力。在终端使用者的电脑上使用telnet程序,用它连接到服务器。终端使用者可以在telnet程序中输入命令,这些命令会在服务器上运行,就像直接在服务器的控制台上输入一样。可以在本地就能控制服务器。要开始一个telnet会话,必须输入用户名和密码来登录服务器。Telnet是常用的远程控制Web服务器的方法(百度百科粘的)。
   从上面可以看出,要想远程操作服务器,必须需要先进行连接和登录,然后通过相应的指令去操作服务器。那怎样进行连接呢?Apache给我们提供相关jar包(commons-net-3.3.jar),TelnetClient是commons-net-3.3.jar下的一个类,用于实现telnet连接。具体见代码:

/** *Telnet操作类 * Created by fblife on 2017/3/28. */public class TelnetUtils {    private static final String TAG = TelnetUtils.class.getSimpleName();    private TelnetClient client;    private BufferedInputStream bis;    private PrintStream ps;    private char prompt = '$';    private GetMessageListener mListener;    public TelnetUtils() {        client = new TelnetClient();    }    /**     * 连接及登录     * @param ip 目标主机IP     * @param port 端口号(Telnet 默认 23)     * @param user 登录用户名     * @param password 登录密码     */    public void connect(String ip, int port, String user, String password) {        try {            client.connect(ip, port);            bis = new BufferedInputStream(client.getInputStream());            ps = new PrintStream(client.getOutputStream());            this.prompt = user.equals("root") ? '#' : '$';            login(user, password);        } catch (Exception e) {            e.printStackTrace();        }    }    /**     * 登录     * @param user     * @param password     */    public void login(String user, String password) {        read("login:");        write(user);        read("Password:");        write(password);        read(prompt + " ");    }    /**     * 读取返回来的数据     * @param info     * @return     */    public String read(String info) {        try {            char lastChar = info.charAt(info.length() - 1);            StringBuffer sb = new StringBuffer();            char ch = (char) bis.read();            while (true) {                sb.append(ch);                if (ch == lastChar) {                    if (sb.toString().endsWith(info)) {                        if (mListener != null){                            mListener.onMessage(sb.toString());                        }                        return sb.toString();                    }                }                ch = (char) bis.read();            }        } catch (Exception e) {            e.printStackTrace();        }        return null;    }    /**     * 写指令     * @param instruction     */    public void write(final String instruction) {        try {            ps.println(instruction);            ps.flush();        } catch (Exception e) {            e.printStackTrace();        }    }    /**     * 向目标发送命令字符串     * @param command     * @return     */    public String sendCommand(String command) {        try {            write(command);            return read(prompt + " ");        } catch (Exception e) {            e.printStackTrace();        }        return null;    }    /** * 关闭连接 */    public void disconnect() {        try {            if (client != null)                client.disconnect();            if (in != null)                in.close();            if (ps != null)                ps.close();        } catch (Exception e) {            e.printStackTrace();        }    }    public interface GetMessageListener{        void onMessage(String info);    }    public void setListener(GetMessageListener mListener) {        this.mListener = mListener;    }}

Activivty 中代码比较简单,但是需要注意的是:Telnet的相关操作都需要在子线程中去操作。代码如下:

public class CameraConfigActivity extends BaseActivity implements TelnetUtils.GetMessageListener, View.OnClickListener {    private static final String TAG = CameraConfigActivity.class.getSimpleName();    private Context mContext;    private TelnetUtils telnet;    private TextView tv_mess;    private ExecutorService singleThreadExecutor;    private EditText ed_send;    private Button bu_send;    private InputMethodManager imm;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main3);        mContext = this;        initView();        singleThreadExecutor = Executors.newFixedThreadPool(3);        imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);    }    private void initView() {        tv_mess = (TextView) findViewById(R.id.tv_mess);        ed_send = (EditText) findViewById(R.id.ed_send);        bu_send = (Button) findViewById(R.id.bu_send);        bu_send.setOnClickListener(this);    }    @Override    protected void onResume() {        super.onResume();        telnet = new TelnetUtils();        telnet.setListener(this);        singleThreadExecutor.execute(new Runnable() {            @Override            public void run() {                telnet.connect("192.168.21.100", 23, "root", "123");            }        });            }    @Override    public void onMessage(final String info) {       runOnUiThread(new Runnable() {           @Override           public void run() {               if (info != null){                   String s = tv_mess.getText().toString();                   tv_mess.setText(s + "\n" + info);               }           }       });    }    @Override    protected void onDestroy() {        super.onDestroy();        telnet.disconnect();        singleThreadExecutor.shutdown();//关闭线程    }    @Override    public void onClick(View v) {        final String send = ed_send.getText().toString();        imm.hideSoftInputFromWindow(ed_send.getWindowToken(),0);        ed_send.setText("");        singleThreadExecutor.execute(new Runnable() {            @Override            public void run() {                if (send == null)                    return;                telnet.sendCommand(send);            }        });    }    @Override    public boolean onKeyDown(int keyCode, KeyEvent event) {        if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN){            finish();            return true;        }        return super.onKeyDown(keyCode, event);    }}

三个对文件操作的Linux指令:
chmod u+x 文件名 修改文件的权限。

echo -e "写入文件的内容" > 文件名  把内容写入文件(覆盖原有内容)。
echo -e "写入文件的内容" >> 文件名  把内容写入文件(追加在原有内容后面)。

sed -i '45c "修改的内容" ' 文件名 替换文件某一行的内容(需要加上 -i,否则不会修改文件,只写入到内存中)。

2 0