吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 12625|回复: 45
收起左侧

[Java 原创] 【原创源码】 java实现简单远程监控(源码+截图)

  [复制链接]
葬天VS晓伟 发表于 2016-3-27 19:44
早些时候跟朋友交流了了java的API什么的,然后弄了个简单的java版本的远程监控,功能实现很简单。

思路:建立socket,也就是建立了连接,就可以传数据,事实上也不存在什么远程控制的api,其实是利用数据来模拟控制的,比如同步画面就是靠不断截图然后传过来图片数据进行显示。而控制,就是监听一些事件,例如鼠标移动,将移动的位置信息传过去,那边做出响应。因为技术时间有限,并不是很完善,键盘的监听也没实现。


主要源码如下:client端
[Java] 纯文本查看 复制代码

package cn.wuaipojie.util;

import java.awt.Container;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class client {

	@SuppressWarnings("resource")
	public static void main(String[] args) {
		/**使用
		 * do{
		 * 
		 * }while(false);
		 * 编码形式避免多个return出现
		*/
		do{
			String link = JOptionPane.showInputDialog("输入连接的ip和端口,以\":\"隔开");
			if (link == null) {
				break;
			}
			int sr = link.lastIndexOf(':');
			if( sr == -1){
				JOptionPane.showMessageDialog(null, "请使用正确分隔符");
				break;
			}
			String ip = link.substring(0, sr);
			String port = link.substring(sr+1);
		
			Socket socket = null;
			try {
				socket = new Socket(ip, Integer.parseInt(port));
			} catch (NumberFormatException e) {
				JOptionPane.showMessageDialog(null, "未知端口");
				break;
			} catch (UnknownHostException e) {
				JOptionPane.showMessageDialog(null, "未知主机");
				break;
			} catch (IOException e) {
				JOptionPane.showMessageDialog(null, "连接建立错误");
				break;
			}
			try {
				DataInputStream in = new DataInputStream(socket.getInputStream());
				final DataOutputStream out = new DataOutputStream(socket.getOutputStream());
				final JFrame jf = new JFrame("java远程监控  - 吾爱破解 葬天VS晓伟");
				jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				double height = in.readDouble();
				double width = in.readDouble();
				jf.setVisible(true);
				jf.setSize((int)width+30,(int)height+55);
				jf.enableInputMethods(false);
				Container con = jf.getContentPane();
				final JPanel panel = new JPanel();
				final JLabel screen = new JLabel();
				panel.add(screen);
				//对面板添加鼠标监控
				screen.addMouseMotionListener(new MouseMotionListener() {
					
					@Override
					public void mouseMoved(MouseEvent e) {
						try {
							out.writeByte(MyEvent.MOVED);
							out.writeInt(e.getX());
							out.writeInt(e.getY());
							out.flush();
						} catch (IOException e1) {
							e1.printStackTrace();
						}
					}
					@Override
					public void mouseDragged(MouseEvent e) {
						try {
							out.writeByte(MyEvent.DRAGGED);
							out.writeInt(e.getX());
							out.writeInt(e.getY());
							out.flush();
						} catch (Exception e2) {
						}
						
					}
				});
				screen.addMouseListener(new MouseListener() {
					//响应鼠标释放事件
					@Override
					public void mouseReleased(MouseEvent e) {
						try {
							out.writeByte(MyEvent.RELEASED);
							out.writeInt(e.getMaskForButton(e.getButton()));
							out.flush();
						} catch (Exception e2) {
						}
					}
					//响应鼠标按下事件
					@Override
					public void mousePressed(MouseEvent e) {
						try {
							//传送事件标志 p代表鼠标点击
							out.writeByte(MyEvent.PRESSED);
							//传送事件信息 将鼠标点击事件MouseEvent转换为InputEvent便于服务端处理
							out.writeInt(e.getMaskForButton(e.getButton()));
							out.flush();
						} catch (IOException e1) {
							e1.printStackTrace();
						}
					}
					@Override
					public void mouseExited(MouseEvent e) {
					}
					@Override
					public void mouseEntered(MouseEvent e) {
					}
					@Override
					public void mouseClicked(MouseEvent e) {
					}
				});
				screen.addMouseWheelListener(new MouseWheelListener() {
					/**
					 * 发送鼠标滚轮事件,e.getWhellRotation()为滚轮滑动的单位计量,正值为向下滚动,负值为向上滚动
					 */
					@Override
					public void mouseWheelMoved(MouseWheelEvent e) {
						try {
							out.writeByte(MyEvent.WHELL);
							out.writeInt(e.getWheelRotation());
							out.flush();
						} catch (IOException e1) {
							e1.printStackTrace();
						}
					}
				});
				jf.addKeyListener(new KeyListener() {
					
					@Override
					public void keyTyped(KeyEvent e) {
						// TODO Auto-generated method stub
						
					}
					
					@Override
					public void keyReleased(KeyEvent e) {
						try {
							out.writeByte(MyEvent.KEY_RELEASED);
							out.writeInt(e.getKeyCode());
							out.flush();
							jf.setTitle("释放按键:"+e.getKeyCode());
						} catch (IOException e1) {
							e1.printStackTrace();
						}
						
					}
					
					@Override
					public void keyPressed(KeyEvent e) {
						jf.setTitle("按下按键:"+e.getKeyCode());
						try {
							out.writeByte(MyEvent.KEY_PRESSED);
							out.writeInt(e.getKeyCode());
							out.flush();
						} catch (IOException e1) {
							e1.printStackTrace();
						}
						
					}
				});
				JScrollPane scrollPane = new JScrollPane(panel);
				con.add(scrollPane);
				//开启屏幕显示线程
				new showPic(in, screen, jf).start();

			} catch (Exception e) {
			}
		}while(false);
	}
}

class showPic extends Thread{
	DataInputStream in;
	JLabel screen;
	JFrame jf;
	public showPic(DataInputStream in,JLabel screen,JFrame jf) {
		this.in = in;
		this.screen = screen;
		this.jf = jf;
	}
	@Override
	public void run() {
		while(true){
			try {
				byte[] b = new byte[in.readInt()];
				in.readFully(b);
				screen.setIcon(new ImageIcon(b));
				jf.repaint();
			} catch (IOException e) {
				JOptionPane.showMessageDialog(null, "远程服务端已被关闭,将自动退出");
				System.exit(0);
			}
		}
	}
}


servlet端:
[Java] 纯文本查看 复制代码
package cn.wuaipojie.util;

import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

public class service {
	
	final static int WIDTH = 320;
	final static int HEIGHT = 70;

	public static void main(String[] args) {
		Dimension ds = Toolkit.getDefaultToolkit().getScreenSize();
		//计算窗口居中
		int position_y = (int)((ds.getHeight()-HEIGHT)/2);
		int position_x = (int)((ds.getWidth()-WIDTH)/2);
		final JFrame jf = new JFrame("远程监控服务端 - 吾爱破解 葬天VS晓伟");
		jf.setResizable(false);
		jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		jf.setVisible(true);
		JPanel jPanel = new JPanel();
		final JButton startButton = new JButton("开启");
		final JButton stopButton = new JButton("停止");
		stopButton.setEnabled(false);
		/**
		 * 点击  "开启" 按钮
		 */
		startButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				ServerSocket serverSocket = null;
				int i;
				//申请端口,成功则跳出,失败则继续申请 固定为从1024递增申请,也可以修改为随机数申请方式
				for(i = 1024; i < 65535; i++){
					try {
						serverSocket = new ServerSocket(i);
						break;
					} catch (Exception e) {
						continue;
					}
				}
				//提示建立连接的ip和端口
				String link = GetIp.getHostIp()+":"+i;
				JOptionPane.showMessageDialog(jf, "已建立连接:"+link+",点击确定将复制到剪贴板");
				Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard(); 
		        Transferable tText = new StringSelection(link); 
		        clip.setContents(tText, null);
		        startButton.setEnabled(false);
		        stopButton.setEnabled(true);
		        new acceptSocket(serverSocket).start();
			
			}
		});
		/**
		 * 点击 "停止" 按钮
		 * 
		 */
		stopButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				//退出当前程序
				System.exit(0);
			}
		});
		jPanel.add(startButton);
		jPanel.add(stopButton);
		jf.add(jPanel);
		jf.setSize(WIDTH, HEIGHT);
		jf.setLocation(position_x, position_y);
		
	}
}	

/**
 * 得到当前屏幕显示数据的线程体
 * 
 * @author zo
 *
 */
class picThread extends Thread{
	private DataOutputStream data;
	public picThread(DataOutputStream data) {
		this.data = data;
	}
	@Override
	public void run() {
		Toolkit toolkit = Toolkit.getDefaultToolkit();
		Dimension dimension = toolkit.getScreenSize();
		double height = dimension.getHeight();
		double width = dimension.getWidth();
		try {
			data.writeDouble(height);
			data.writeDouble(width);
			data.flush();
			Rectangle rectangle = new Rectangle(dimension);
			while(true){
				byte[] image = createImage(rectangle);
				data.writeInt(image.length);
				data.write(image);
				data.flush();
			}
		} catch (IOException e) {
			this.interrupt();
		}
	}
	
	//获取并压缩屏幕显示数据
	private byte[] createImage(Rectangle rectangle){
		Robot robot;
		try {
			robot = new Robot();
			BufferedImage bufferedImage = robot.createScreenCapture(rectangle);
			ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
			JPEGImageEncoder jpegImageEncoder = JPEGCodec.createJPEGEncoder(outputStream);
			jpegImageEncoder.encode(bufferedImage);
			return outputStream.toByteArray();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}

/**
 * 监控连接请求线程体(允许多个客户端同时连接)
 * @author zo
 *
 */
class acceptSocket extends Thread{
	ServerSocket ss;
	public acceptSocket(ServerSocket ss) {
		this.ss = ss;
	}
	@Override
	public void run() {
		while(true){
			Socket client;
			DataOutputStream data = null;
			DataInputStream mouse = null;
			try {
				client = ss.accept();
				data = new DataOutputStream(client.getOutputStream());
				mouse = new DataInputStream(client.getInputStream());
			} catch (IOException e) {
				JOptionPane.showMessageDialog(null, "建立服务失败");
				return;
			}
			new picThread(data).start();
			new mouseInfo(mouse).start();
		}
	}
}

class mouseInfo extends Thread{
	DataInputStream in;
	
	public mouseInfo(DataInputStream in) {
		this.in = in;
	}
	@Override
	public void run() {
		while(true){
			toMoveMouse();
		}
	}
	
	public void toMoveMouse(){
		try {
			Robot robot = new Robot();
			byte event = in.readByte();
			/**
			 * 判断鼠标事件
			 * 规定数据流发过来的第一个byte为鼠标事件标志
			 * 详细定义见 MyEvent
			 */
			switch (event) {
			case MyEvent.PRESSED:
				robot.mousePress(in.readInt());
				break;
			case MyEvent.RELEASED:
				robot.mouseRelease(in.readInt());
				break;
			/**
			 * 模拟响应鼠标移动和拖拽事件  
			 * 拖拽的过程: 拖拽开始-》接收到press事件,且没有接收到release事件。 拖拽过程-》鼠标移动。拖拽结束-》接收到release事件
			 * press和release事件由上面的MyEvent.PRESSED和MyEvent.RELEASE模拟,拖拽实际上只需要负责模拟移动鼠标的操作即可
			 */
			case MyEvent.MOVED:
			case MyEvent.DRAGGED:
				robot.mouseMove(in.readInt(), in.readInt());
				break;
			//响应鼠标滚轮事件
			case MyEvent.WHELL:
				robot.mouseWheel(in.readInt());
				break;
			case MyEvent.KEY_PRESSED:
				robot.keyPress(in.readInt());
				break;
			case MyEvent.KEY_RELEASED:
				robot.keyRelease(in.readInt());
				break;
			default:
				break;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


完整的项目: java小玩意.rar (46.97 KB, 下载次数: 314)

注意:其中client为客户端(控制端),servlet为服务端(被控制端),直接运行两个jar文件即可。(运行jar文件必须在电脑安装jdk。)

运行截图:
QQ图片20160327190618.png QQ图片20160327190623.png


觉得不错的朋友,求点热心和CB鼓励一下,以后有更多的好东西会一起共享给论坛的朋友的,大家一起学习 和交流





免费评分

参与人数 14吾爱币 +2 热心值 +14 收起 理由
五五66 + 1 + 1 我很赞同!
lauwey + 1 + 1 已经处理,感谢您对吾爱破解论坛的支持!
想你每一天 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
huxiangsky + 1 用心讨论,共获提升!
ja2007gg + 1 鼓励转贴优秀软件安全工具和文档!
a769872964 + 1 用心讨论,共获提升!
小朋友呢 + 1 我好像升级了O(∩_∩)O
Cizel + 1 感谢发布原创作品,吾爱破解论坛因你更精彩.
fly农夫三拳 + 1 不错,请问这是j2ME的范围?
-Zing- + 1 谢谢@Thanks!
myqqq + 1 小白电脑是不会装jdk的
流月汐志 + 1 用心讨论,共获提升!
浅唱、聆听 + 1 用心讨论,共获提升!
有你的远方 + 1 我很赞同!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| 葬天VS晓伟 发表于 2016-6-4 19:00
a769872964 发表于 2016-6-4 18:49
大神 下载了东西 却不知道怎么用啊~~ 有么有教程啊  已加热

我是在虚拟机上测试的(一个是自己的电脑,一个是虚拟机),在其中一个装上客户端,另一个装服务端(也不算装,因为直接就能打开了),这个前提是你电脑装了jdk(jdk不会的话百度下就有了),然后开启客户端和服务端,就能用服务端控制客户端了
 楼主| 葬天VS晓伟 发表于 2016-6-13 09:44
snfnje 发表于 2016-6-13 08:50
不在同一个网段可以用吗?比如说在家里远程连接公司里的电脑

这个没尝试过喔,你可以试试。
有你的远方 发表于 2016-3-27 19:54
anhao 发表于 2016-3-27 20:07
学习一下,
棉花 发表于 2016-3-27 20:13
大牛啊 。。。
m13414907 发表于 2016-3-27 20:46
有密码啊,大牛~~~~
q65686488 发表于 2016-3-27 20:53 来自手机
我来看看java的学习,大牛,我顶你
 楼主| 葬天VS晓伟 发表于 2016-3-27 21:13
m13414907 发表于 2016-3-27 20:46
有密码啊,大牛~~~~

密码在旁边注释有啊。
m13414907 发表于 2016-3-27 21:18
葬天VS晓伟 发表于 2016-3-27 21:13
密码在旁边注释有啊。

大牛发我一下吧,我怎么没看到呢~~
 楼主| 葬天VS晓伟 发表于 2016-3-27 21:21
m13414907 发表于 2016-3-27 21:18
大牛发我一下吧,我怎么没看到呢~~

解压密码为
123456
myqqq 发表于 2016-3-27 22:21
感谢分享源码              
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-15 12:22

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表