最近项目有个需求,需要在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连接。具体见代码:
Activivty 中代码比较简单,但是需要注意的是:Telnet的相关操作都需要在子线程中去操作。代码如下:
三个对文件操作的Linux指令:
chmod u+x 文件名 修改文件的权限。
echo -e "写入文件的内容" > 文件名 把内容写入文件(覆盖原有内容)。
echo -e "写入文件的内容" >> 文件名 把内容写入文件(追加在原有内容后面)。
sed -i '45c "修改的内容" ' 文件名 替换文件某一行的内容(需要加上 -i,否则不会修改文件,只写入到内存中)。
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,否则不会修改文件,只写入到内存中)。