java Telnet 监控磁盘信息

 

 题记:

        最近弄一个视频有关的项目,有很多的视频存储,所以存储这块就有必要进行一些监控,及内容淘汰等策略。存储设备都是分布式部署的,我们不希望在server上安装特别的插件,如何获取远程磁盘信息,成了我最大的障碍。目前采用的方式是java建立telnet连接,发送操作系统命令,解析返回信息,在此整理下。

 

摘要:

         这是我第一次接触到java获取远程操作系统信息的工作,刚拿到需求有点两眼一抹黑,百度、Google的不少资料。总结起来大概三种类型:

        1:Apache的commons.io中有一个工具类方法:FileSystemUtils.freeSpaceKb(path),可以通过共享目录方式获取磁盘剩余信息。

        2:JConfig拓展工具,调用系统底层命令,获取磁盘信息。参考资料:http://huangyunzeng.iteye.com/blog/1142873

        3:使用jni技术,这个是解决所有和os相关的操作的万能利器了。这个没深入研究过,不会,在此就不多提了。

        在看到Apache的FileSystemUtils的时候,在本机测试了下,有点激动了。不过很快发现,这只能获取本地磁盘信息,要获取远程磁盘信息只能建立共享目录。这显然不能满足我们的要求,不过正是FileSystemUtils工具包的实现原理给了我启发:调用操作系统命令,然后解析,获取信息是一种不错的方式。

    Runtime.getRuntime().exec(String command) //启动进程执行操作系统命令

       

         现在的问题就变成:建立远程连接,调用操作系统命令,然后解析返回值。我只要找到一种建立连接的方式就能完成任务了。顺着这个思路,后来选择了Telnet,理由如下:

         a:Apache中收录了Telnet. org.apache.commons.net.telnet.TelnetClient,可以直接使用Client,不用再考虑socket Server端的实现等。
         b:系统中一般都已自带了telnet,只需启动telnet服务就好,不用安装其他的插件。

         c:为不用更安全的SSH协议建立连接呢?因为我程序中需要识别操作系统类型。telnet在建立连接后,有一个头信息,根据这个头信息能基本判断是Window,还是Linux。而换成SSH后,建立连接就不能这么方便的获取操作系统类型了。在此,我就暂时恶心一下,用Telnet吧。

 

正文:

一、telnet暨磁盘监控原理简介

二、分享部分实现代码

 

一、telnet暨磁盘监控原理简介

        如果你仔细阅读了摘要的内容,相信已经明了本文telnet远程监控磁盘信息的大概原理了。在此再提一遍,是为了补充一些更细节的内容。

二:部分实现代码:

1:成员变量及构造方法

	private TelnetClient telnet = new TelnetClient("VT220"); //"VT220" 为处理windows下的乱码问题
	private InputStream in;

	private PrintStream out;

	private char prompt = "$" //普通用户结束
           private int os = -1; //操作系统类型

 

	public TelnetShell(String ip, int port, String user, String password)
			throws SocketException, IOException {
		telnet.connect(ip, port);
		in = telnet.getInputStream();
		out = new PrintStream(telnet.getOutputStream());
		// 根据root用户设置结束符
		this.prompt = user.equals("root") ? '#' : '>';
		login(user, password);
	}


建立连接:

	/**
	 * 建立telnet连接
	 * 
	 * <p>
	 * 根据telnet 头信息识别操作系统类型,并处理连接异常
	 * 
	 * @param user
	 * @param password
	 */
	public void login(String user, String password) throws SocketException {
		String thead = readUntil("login:");
		setOsType(thead); // 根据telnet 头信息获取操作系统类别
		write(user);
		readUntil("password:");
		write(password);

		// 处理连接异常
		boolean loginSuccess = judgeLogin();
		System.out.println("loginSuccess or not ? " + loginSuccess);
		if (loginSuccess) {
			readUntil(prompt + "");
		} else {
			throw new SocketException("Login Failed...");
		}
	}


读/写操作

	/**
	 * 读取分析结果 
	 * 
	 * <p>
	 * “pattern” 指明IO读取的结束位置
	 * <p>
	 * 为避免Windows返回中“<dir>”的干扰
	 * 
	 * @param pattern
	 * @return
	 */
	public String readUntil(String pattern) {
		try {
			char lastChar = pattern.charAt(pattern.length() - 1);
			StringBuffer sb = new StringBuffer();
			char ch = (char) in.read();

			System.out.print(ch);
			while (ch != -1) {
				sb.append(ch);
				if (ch == lastChar) {
					if (sb.toString().toLowerCase().endsWith(pattern)) {
						// 避免windows下因捕获‘>’中断
						if (!sb.toString().toLowerCase().endsWith("<dir>")) {
							System.out.println("提取完毕");
							return sb.toString();
						}
					}
				}

				ch = (char) in.read();
				System.out.print(ch);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}


 

	/**
	 * 写操作
	 * 
	 * @param value
	 */
	public void write(String value) {
		try {
			out.println(value);
			out.flush();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


识别系统类型,执行命令

	/**
	 * 设置操作系统类型
	 * 
	 * @param telnetHeadInfo
	 */
	public void setOsType(String telnetHeadInfo) {
		if (null == telnetHeadInfo || "".equals(telnetHeadInfo))
			return;

		if (telnetHeadInfo.indexOf("Microsoft") != -1) {
			os = 1;
		} else if (telnetHeadInfo.indexOf("Kernel") != -1) {
			os = 2; // x-nix
		} else
			os = 3;
	}


 

	/**
	 * 向目标发送命令字符串
	 * 
	 * @param command
	 * @return
	 */
	public String sendCommand(String command) {
		try {
			write(command);
			return readUntil(prompt + "");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}


关闭连接

	/**
	 * 关闭连接
	 */
	public void disconnect() {
		try {
			telnet.disconnect();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


这样,建立连接、识别操作系统,执行命令,读取返回等都基本完成了。可以说Telnet远程获取操作系统信息的大部分代码已经完成。当然,在提供外层封装上,你也可以仿照Apache的FileSystemUtils写一个工具类,采用一些工厂类的模式方便调用,拓展。

 

最后,可能您已经发现了,本文的标题是要监控“磁盘信息”,但我完全可以获取跟多信息。有了这个telnetShell.java后,我完全可以发送其他系统命令,获取更多信息。这就看你怎么发挥了,呵呵。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值