Android之telnet编程

Android之telnet编程

前段时间遇到要在Android设备上使用telnet登陆一个设备(PC端也可以),并发送命令的问题。根据当时的demo(服务器端使用的telnet方式),一直不能执行,总之就是不能登陆。后来得高人指点,写了一个AsyncTask的方式来连接telnet。终于改编后应用到项目中,成功登陆并发送telnet命令了(第一次写csdn,还不够完善,请大家指点)
整个过程其实就是类似于PC电脑上的运行一次CMD黑框框,但是这个需要登陆输密码和发命令。可以下载一个叫Telnet的APP,那个有黑框框,比较高大上,我这个只是简易应用。
直接上代码:

private class RunTelnet extends AsyncTask{
        private String h="";  //host:telnet的IP地址
        private String u="";  //user:用户名
        private String p="";  //password:密码
        private TelnetClient telnet;
        private InputStream in;
        private PrintStream out;
        public RunTelnet(String h, String u, String p){
            this.h=h;
            this.u=u;
            this.p=p;
        }
        /* (non-Javadoc)
         * @see android.os.AsyncTask#doInBackground(java.lang.Object[])
         */
        @Override
        protected Void doInBackground(Void... params) {
            telnet = new TelnetClient();
            try {
                telnet.connect(h, 2323);//连接telnet
                in = telnet.getInputStream();//获取输入流
                out = new PrintStream(telnet.getOutputStream());//输出流
        //      telnet.setKeepAlive(true);
                Thread mThread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        try {
                            readUntil("login: ");//“黑框框”上显示login,这时要输入用户名
                            out.println(u + "\r");//输上用户名
                            out.flush();
                            try {
                            //等上1秒钟
                                TimeUnit.SECONDS.sleep(1);
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                            readUntil("Password: ");//“黑框框”上显示Password,这时要输入密码
                            out.println(p + "\r");//输上密码
                            out.flush();
                            try {
                            //等上1秒钟
                                TimeUnit.SECONDS.sleep(1);
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                            readUntil("#");//#意味着可以输入控制命令
                            out.println(CMD + "\r");//输上命令,CMD是个字符串
                            out.flush();

                            try {
                            //等上1秒钟
                                TimeUnit.SECONDS.sleep(1);
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                            //我这发送的是一条获取命令,这里“黑框框”返回一个list,接下来获取到S中
                            int count = 0;
                            while (count == 0) {
                                count = in.available();
                            }
                            byte[] b = new byte[count];
                            int readCount = 0; // 已经成功读取的字节的个数
                            while (readCount < count) {
                                readCount += in.read(b, readCount, count
                                        - readCount);
                            }
                            String s = new String(b, "UTF-8");
                            //对获取到的数据进行处理,不必理会
                            uploadResult(h, turnToMacs(s));
                            /*当然有想法的人当然会想到在前面声明个handler,在这里就可以和UI主线程交流,将s展现在Android屏幕上了*/
                        } catch (Exception e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        finally{
                        //最终退出
                            out.println("exit\r\n");
                            out.flush();
                            //断开连接
                            disconnect();

                        }
                    }
                });
                mThread.start();//线程开始运行
                //mThread.stop();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
        //逐字检查输入流(in),直到黑框框中显示以“pattern”结尾时
        //增加了一个i<1000的条件,免得一直等下去
        public String readUntil(String pattern) {
            try {
                char lastChar = pattern.charAt(pattern.length() - 1);
                StringBuffer sb = new StringBuffer();
                //boolean found = false;
                //获取输入流的最后一个字节
                char ch = (char) in.read();
                int i=0;
                //判断“黑框框”的前1000个字节,免得一直等下去
                while (i<1000) {
                    sb.append(ch);
                    //先比较最后一个字节和所要求的最后一个字节
                    if (ch == lastChar) {
                    //再判断输入流的结尾是不是所要求的字符串
                        if (sb.toString().endsWith(pattern)) {
                            return sb.toString();
                        }
                    }
                    ch = (char) in.read();
                    i++;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
        //断开连接
        public void disconnect() {
            try {
            //关闭输入、输出流
                in.close();
                out.close();
                telnet.disconnect();
                System.out.println("telnet.disconnect");
            } catch (Exception e) {
                e.printStackTrace();
            }

        }

    }

整个代码中有很多不稳定的地方,考虑到连接telnet设备时,输入用户名、密码等需要一定的时间,而且设备返回到Android设备也没那么及时,所以加上了等待一秒,i<1000这样的没有道理的代码。如果有比较好的比较稳定的代码,希望大家能告诉我。第一次写csdn,比较乱,思路也不够清晰,请见谅,可以直接看代码。

你可能感兴趣的:(android开发)