`
什么世道
  • 浏览: 222447 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

Java实现远程监控之二:代码实现及其优化

阅读更多

 

“指尖上的遥控”项目——Java远程监控

 

--by Shadow Walker

上一篇博文已经分析了Java实现远程监控的思路,本篇博文主要分享主要部分的代码实现、

 

用imago.IO封装桌面截图图片发送

 

robot = new Robot();
while (flag) {
// 抓去一张屏幕大小的图片
BufferedImage bgImg = robot.createScreenCapture(rect);

// 将抓取的图片转换为byte数组
ByteArrayOutputStream baous = new ByteArrayOutputStream();

ImageIO.write(bgImg, "jpeg", baous);
byte[] bytes = baous.toByteArray();
dous.writeInt(bytes.length);// 写入发送图片信息的长度
dous.write(bytes);// 写入组成图片的字节数据
dous.flush();
Thread.sleep(150);
}

 

被控端将所有的鼠标键盘的输入转化为Robot对象的事件回放

 

	/**
	 * 处理控制端发送来的事件对象,调用Robot对象来执行相应的操作
	 * 
	 * @param event
	 *            网络收到的控制端事件对象
	 */
	private void handleEvent(InputEvent event) {
		MouseEvent mouseEvent = null;
		MouseWheelEvent mouseWheelEvent = null;
		KeyEvent keyEvent = null;

		int mouseButtonMask = -1;
		switch (event.getID()) {
		case MouseEvent.MOUSE_MOVED:// 鼠标移动事件
			mouseEvent = (MouseEvent) event;
			robot.mouseMove((int) (mouseEvent.getX()),
					(int) (mouseEvent.getY()));
			break;

		case MouseEvent.MOUSE_PRESSED:// 鼠标按键按下事件
			mouseEvent = (MouseEvent) event;
			mouseButtonMask = getButtonMask(mouseEvent.getButton());// 获取按键标志
			robot.mousePress(mouseButtonMask);
			break;

		case MouseEvent.MOUSE_RELEASED:// 鼠标按键释放事件
			mouseEvent = (MouseEvent) event;
			mouseButtonMask = getButtonMask(mouseEvent.getButton());// 获取按键标志
			robot.mouseRelease(mouseButtonMask);
			break;

		case MouseEvent.MOUSE_WHEEL:// 鼠标中键滚动事件
			mouseWheelEvent = (MouseWheelEvent) event;
			robot.mouseWheel(mouseWheelEvent.getWheelRotation());
			break;

		case MouseEvent.MOUSE_DRAGGED:// 鼠标拖拽事件
			mouseEvent = (MouseEvent) event;
			robot.mouseMove((int) (mouseEvent.getX()),
					(int) (mouseEvent.getY()));
			break;

		case KeyEvent.KEY_PRESSED:// 键盘按键按下事件
			keyEvent = (KeyEvent) event;
			robot.keyPress(keyEvent.getKeyCode());
			break;

		case KeyEvent.KEY_RELEASED:// 键盘按键释放事件
			keyEvent = (KeyEvent) event;
			robot.keyRelease(keyEvent.getKeyCode());
			break;

		default:
			LogTool.INFO("unknown event" + event.getID());
			break;
		}
	}

	/**
	 * 根据发送的Mouse事件对象,转变为通用的Mouse按键代码
	 * 
	 * @param button
	 * @return
	 */
	private int getButtonMask(int button) {
		if (button == MouseEvent.BUTTON1) {
			return InputEvent.BUTTON1_MASK;
		}
		if (button == MouseEvent.BUTTON2) {
			return InputEvent.BUTTON2_MASK;
		}
		if (button == MouseEvent.BUTTON3) {
			return InputEvent.BUTTON3_MASK;
		}
		return -1;
	}

 

 

控制方与被控方之间传输事件

 

	/**
	 * 将监听的动作对象写入输入流中
	 * 
	 * @param event
	 *            监听的事件对象
	 */
	public void sendAction(InputEvent event) {
		try {
			oous.writeObject(event);
		} catch (IOException e) {
			LogTool.ERROR("控制端动作转信息类中写入异常:" + e.getMessage().toString());

		}
	}

 

 

一些小方面的优化:

 

使用Image.IO和JPEGImageEncoder封装jpg图片发送截图图片的时间差异。

 

/**log output
2013-10-18 15:54:00  Image.IO	cost time141	bgImg size:114040
2013-10-18 15:54:00  JPEGImageEncoder	cost time16	bgImg size:114258
*/

 

so,果断采用JPEGImageEncoder封装发送图片

 

	/**
	 * 将背景图片压缩成JPEG并发送到控制端
	 * 
	 * @param rec
	 * @return
	 * @throws IOException
	 */
	private byte[] createImage(Rectangle rec) throws IOException {

		BufferedImage bfImage = robot.createScreenCapture(rec);

		ByteArrayOutputStream baous = new ByteArrayOutputStream();

		JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(baous);

		encoder.encode(bfImage);

		return baous.toByteArray();

	}

 

 

添加第三方监视方,数量不限,可以实现同步的监视,但是不能控制。

因而第一台与服务器连接等客户机即为控制方,以后的客户机均为监视方,显示被控端界面的信息。

 

/**
	 * 在指定端口上启动一个服务器
	 * 
	 * @param port
	 *            :服务器开端口
	 */
	public void setUpServer(int port) {
		try {
			// 1.建立绑定在指定端口上的服务器对象
			@SuppressWarnings("resource")
			ServerSocket server = new ServerSocket(port);
			LogTool.INFO("服务器创建成功" + port);
			// 2.当有客户机连接时,等待方法就会返回,返回一个代表与客户端连接的对象
			while (true) {
				if (state == true) {// 第一个客户机连接为控制端,以后连接的均为监视端
					// 让服务器处于循环待机状态
					Socket client = server.accept();// 可能会发生堵塞
					LogTool.INFO("Incoming"
							+ client.getRemoteSocketAddress().toString());
					
					LogTool.INFO("处理线程已启动,正处理登录操作! -->控制端");
					RemoteScreenThread rct = new RemoteScreenThread(client);
					rct.start();
					// 开启被控端动作还原线程
					RemoteRobotThread rrt = new RemoteRobotThread(client);
					rrt.start();
					state = false;
					
				} else {// 如若服务器已经连接上,这客户机为监视端
						// 让服务器处于循环待机状态
					Socket client = server.accept();// 可能会发生堵塞
					LogTool.INFO("Incoming"
							+ client.getRemoteSocketAddress().toString());
					
					LogTool.INFO("处理线程已启动,正处理登录操作! ———>监视端");
					
					RemoteScreenThread rct = new RemoteScreenThread(client);
					MonitorTools.addClient(rct);
					
					LogTool.INFO("添加监视端对象成功");
					//将截图信息群发到监视端里面
					MonitorTools.castScreen();
					
//					RemoteScreenThread rct = new RemoteScreenThread(client);
//					MonitorTools.addClient(client);
				}
			}
		} catch (Exception ef) {
			LogTool.ERROR("被控端开启端口监听器中出错:" + ef.getMessage());
		}
	}
}

 

 

 

后台写一个监视辅助类,主要存储监视方对象,并对监视方发送被控端截图信息。

由于该类不用创建对象,故定义为静态类,所有方法均为静态方法。

 

/**
 * 监控工具类,将所有的的客户端线程添加到队列中
 * @author YangKang
 *
 */
public class MonitorTools {
	private static ArrayList<RemoteScreenThread> rctlist = new ArrayList<RemoteScreenThread>();//连接的监视端队列
	private MonitorTools(){}//不需要创建类对象,构造器则私有
	
	
	/**
	 * 将一个客户机对应的处理线程加入到队列中
	 * @param st 处理线程对象
	 */
	public static void addClient(RemoteScreenThread rct) {
		try {
			//通知大家一声,有人上线了
//			castMsg(cct.getOwnerUser(),"我上线了,目前在线人数:"+stlist.size());
			rctlist.add(rct);
		} catch (Exception e) {
			LogTool.ERROR("MonitorTools类中线程对象添加到队列失败"+e.getMessage().toString());
		}
	}
	
	
	/**
	 * 将客户端发送过来的消息转发送给队列中的其他客户端处理对象
	 * @param sender 发送者用户对象
	 * @param msg	要发送的消息内容
	 * @throws Exception IO异常
	 */
	public static void castScreen()  {
		for (int i = 0; i < rctlist.size(); i++) {
			rctlist.get(i).start();;
		}
	}
}

 

 

 

源代码打包上传地址:http://pan.baidu.com/s/1cMqOL

 

 

 

希望大家多多支持和指正。

1
0
分享到:
评论
2 楼 什么世道 2013-10-31  
784222511 写道
那个密码框有什么用?

监控前是为了安全起见设置一个密码的,但是发博客的时候还没有加上去.
1 楼 784222511 2013-10-29  
那个密码框有什么用?

相关推荐

    基于JAVA CS远程监控系统软件的实现(源代码+论文).rar

    下面将详细讨论Java CS远程监控系统的实现及其关键技术。 1. **Java技术基础** Java是一种广泛使用的编程语言,以其“一次编写,到处运行”的特性闻名。Java虚拟机(JVM)使得Java程序可以在不同的操作系统上运行...

    java1072基于Java远程监控系统软件的实现2.pdf

    《基于Java的远程监控系统软件实现》 随着网络技术的飞速发展,远程监控系统软件在各个领域的应用越来越广泛,其重要性和实用性不言而喻。基于Java的远程监控系统软件打破了物理空间的限制,使得用户无需亲临现场,...

    基于BS模式的视频远程监控系统

    本系统基于B/S架构,采用Java作为开发平台,结合JMF技术和IP组播技术实现了视频远程监控的功能。系统主要由以下几个部分组成: 1. **前端界面**:用户通过浏览器访问系统,界面简洁易用,支持多用户同时操作。 2....

    远程监控实验报告,程序,

    远程监控技术是现代信息技术的重要组成部分,它允许用户通过网络对远程设备、系统或环境进行实时监控,以便及时发现并处理问题。在这个实验报告中,我们将深入探讨远程监控的原理、实施步骤以及相关程序的设计。 ...

    基于Java的网格计算框架及其实现

    ### 基于Java的网格计算框架及其实现 #### 一、引言 随着信息技术的飞速发展,网格计算作为一种新型的分布式计算模式,在处理大规模科学计算与工程计算问题时展现出巨大的潜力。本文旨在探讨一种基于Java语言的...

    Java虚拟机-jvm故障诊断与性能优化-源码

    - **JMX**:Java管理扩展,允许远程监控和管理应用程序。 5. **JVM故障诊断** - **堆dump分析**:通过jmap生成堆转储文件,使用MAT、VisualVM等工具分析内存泄漏。 - **线程dump**:jstack命令获取线程状态,...

    Java性能优化技巧集锦.pdf

    - 如何通过Java代码实现循环的性能优化。 4. Java内存管理和堆栈使用(1.4节): - Java内存结构中堆(Heap)和栈(Stack)的特性及其对性能的影响。 - 对象创建时内存分配的优化方法。 5. Java设计模式(1.5节...

    使用Java来监视系统进程的解决方案

    因此,我们不能依赖远程监控或者跨平台的解决方案。 解决问题的关键点有两个:一是如何启动并运行第二个JVM中的测试程序,二是如何从第一个JVM中监控第二个JVM及其进程。 对于第一个关键点,可以通过Java的`java....

    java内存查看工具jvisualvm

    jvisualvm支持通过JMX远程连接到Java应用,实现远程监控和管理。这使得开发者可以在本地使用jvisualvm来分析部署在远程服务器上的应用程序。 5. **插件扩展** jvisualvm支持丰富的插件系统,用户可以通过安装插件...

    Java工程师成神之路~-HollisChuang's Blog1

    JMX(Java Management Extensions)则允许远程监控和管理Java应用程序,这对于系统的运维和故障排查非常有用。同时,学习编写各种模拟内存溢出和栈溢出的程序,可以帮助我们更好地理解内存管理机制。 当遇到性能...

    JavaRPC框架

    Java RPC(Remote Procedure Call)框架是一种允许分布式系统中不同节点之间进行远程调用的技术。它使得开发者能够像调用本地方法一样调用远端服务,极大地简化了分布式系统的开发。在给定的“Java RPC框架”中,...

    jprofiler监控工具使用说明

    5. **选择JDK版本**:与本地监控相同,选择远程监控所需的JDK版本。 6. **配置端口号**:与本地监控相同,设置远程监控的端口号。 7. **启动界面方式**:选择远程监控的启动模式。 #### 四、主要功能介绍 **1. ...

    基于android的智能家居监控系统的设计与实现.docx

    根据提供的文档信息,我们可以归纳出以下相关知识点: ### 一、项目背景与意义 #### 1.1 背景介绍 - **概念提出**:20世纪...这些知识点对于理解基于Android的智能家居监控系统的开发过程及其技术实现具有重要意义。

    良田高拍仪开发服务端demo-java.zip_java服务端代码_onto4x9_良田_良田高拍仪_高拍仪

    服务端代码应集成了这些功能,通过网络调用来实现远程操作。例如,用户可以通过API请求拍摄图片、调整图像质量、保存文档为多种格式等。 5. **网络通信**:由于服务端代码通常需要与客户端进行交互,因此会涉及到...

    用java获取CPU占用率

    在IT领域,特别是系统监控与性能分析中,获取CPU占用率是评估系统健康状况和优化资源分配的关键步骤。本文将详细解析如何使用Java语言来获取CPU占用率,这不仅涉及了基本的Java编程技巧,还深入到了操作系统级别的...

    The Java Language Environment

    - **性能优化:** JIT编译提高执行速度。 **2. Java类库** - **基础类库:** 提供了基本的数据类型、输入输出操作等功能。 - **标准类库:** 包括集合框架、并发工具等高级特性。 - **扩展类库:** 可以根据需要...

    【Java核心知识面试】-阿里Java面试集锦.zip

    - JMX:Java管理扩展,用于远程监控和管理Java应用程序。 5. **IO流** - 字节流与字符流:理解两者区别,学习BufferedReader、BufferedWriter、FileInputStream等类的使用。 - NIO(New IO):讲解非阻塞I/O,...

    java performance

    - 使用JMX进行远程监控,诊断内存、CPU和GC问题。 - CPU热点代码定位,分析方法耗时,找出性能瓶颈。 6. **JIT编译器与热点代码**: - 揭秘JIT编译器的工作方式,如何将字节码转化为机器码,提升运行速度。 - ...

    java项目交通灯管理系统

    - **网络编程**:利用Socket编程实现服务器与客户端之间的通信,可用于远程监控功能。 - **数据库连接**(JDBC):通过Java访问MySQL或其他关系型数据库,存储路口信息、历史记录等数据。 #### 图形用户界面开发 - ...

    JAVA基于SNMP网络设备MIB信息采集(论文+源代码).zip

    标题中的“JAVA基于SNMP网络设备MIB信息采集(论文+源代码)”表明这是一个关于使用Java编程语言实现SNMP(简单网络管理协议)来收集网络设备MIB(管理信息库)信息的项目。这个项目可能包含一篇详细论述该主题的论文...

Global site tag (gtag.js) - Google Analytics