Android 实现Telnet终端

本文介绍如何在APP端实现Telnet操作,包括连接、登录服务器的过程,并提供了一个示例项目,展示了如何使用Apache commons-net库进行Telnet交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    最近项目有个需求,需要在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,否则不会修改文件,只写入到内存中)。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值