您的位置:首页 > 编程语言 > Java开发

Java远程屏幕监控案例

2010-09-02 16:30 246 查看
[b]
[b]该案例主要分为两个类文件,Server及其中的内部类,Client及其中的内部类。



大家可以参考。



如对Java远控比较感兴趣可以到我的网站上看一下



我们最近用Java开发的一款“黑天鹅远控”软件,并且为开源软件。


该案例为该软件中的一个功能点的源代码,并且已经整理成为单独的完善的案例。



我们的官方网站网址:


http://www.blackswansoft.com/



你可以在该网站上[b][b]下载


[/b]

[/b]
[b]“黑天鹅远控”软件。网站上发布了更多的java热点技术,欢迎大家参考。


[/b]

QQ:1037729010



Email:
blackswansoft@163.com





[/b]

[/b]





/**

*服务端代码

*

*/

import java.awt.AWTException;

import java.awt.Dimension;

import java.awt.Rectangle;

import java.awt.Robot;

import java.awt.Toolkit;

import java.awt.image.BufferedImage;

import java.io.DataOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.zip.ZipEntry;

import java.util.zip.ZipOutputStream;

import javax.imageio.ImageIO;

public class Server{

public static void main(String args[]) {

SendScreenImg sender=new SendScreenImg();

sender.changeServerPort(30009);//此处可以修改服务端口

new Thread(sender).start();//打开图像传输服务

OperateWindow operate=new OperateWindow();

// operate.changeServerPort(30010);//此处可以修改服务端口

new Thread(operate).start();//打开主机操控服务



//***** 当然 服务器端的端口修改是随时都可以操作的 它实际上是关闭以前的端口 再开启一个新端口 *****//

}

}

/**

* @author LanXJ @doctime 2010-7-8

* 开启一个设定端口的服务,该服务用于向客户端传送主机的屏幕信息,实现客户端对服务器端主机的监控

* 实例化线程类后默认打开DEFAULT_SERVER_PORT=30011 端口实现监听

* 可以通过changeServerPort改变监听端口,也可以通过getServerPort来查询当前监听端口

*/

class SendScreenImg implements Runnable{

public static final int DEFAULT_SERVER_PORT=30011;

private int serverPort;

private Robot robot;

private ServerSocket serverSocket;

private Rectangle rect;

private Dimension screen;

private BufferedImage img;

private Socket socket;

private ZipOutputStream zip;

public SendScreenImg() {

this.serverPort=SendScreenImg.DEFAULT_SERVER_PORT;

try {

serverSocket = new ServerSocket(this.serverPort);

serverSocket.setSoTimeout(86400000);

} catch (IOException e1) {

e1.printStackTrace();

}

try {

robot = new Robot();

} catch (AWTException e) {

e.printStackTrace();

}

screen = Toolkit.getDefaultToolkit().getScreenSize();

rect = new Rectangle(screen);

}

public void changeServerPort(int serverPort){

if(this.serverPort==serverPort)return;

this.serverPort=serverPort;

try {

this.serverSocket.close();

} catch (Exception e) {}

try {

serverSocket = new ServerSocket(this.serverPort);

serverSocket.setSoTimeout(86400000);

} catch (IOException e1) {

e1.printStackTrace();

}

}

public int getServerPort(){

return this.serverPort;

}

public void run() {

while (true) {

try {

System.out.println("等待接收截屏信息");

socket = serverSocket.accept();

zip = new ZipOutputStream(new DataOutputStream(socket.getOutputStream()));

zip.setLevel(9);//为后续的 DEFLATED 条目设置压缩级别 压缩级别 (0-9)

try {

img = robot.createScreenCapture(rect);

zip.putNextEntry(new ZipEntry("test.jpg"));

ImageIO.write(img, "jpg", zip);

if(zip!=null)zip.close();

System.out.println("被控端:connect");

} catch (IOException ioe) {

System.out.println("被控端:disconnect");

}

} catch (IOException ioe) {

System.out.println("错误1");

} finally {

if (socket != null) {

try {

socket.close();

} catch (IOException e) {

}

}

}

}

}

}

/**

* @author LanXJ @doctime 2010-7-8

* 开启一个设定端口的服务,该服务用于接受客户端传来的操作字符串,实现对服务器端主机的操控

* 实例化线程类后默认打开DEFAULT_SERVER_PORT=30012 端口实现监听

* 可以通过changeServerPort改变监听端口,也可以通过getServerPort来查询当前监听端口

*/

class OperateWindow implements Runnable {

public static final int DEFAULT_SERVER_PORT=30012;

private int serverPort;

private ServerSocket serverSocket;

private Robot robot;

public OperateWindow() {

this.serverPort=OperateWindow.DEFAULT_SERVER_PORT;

try {

this.serverSocket = new ServerSocket(this.serverPort);

this.serverSocket.setSoTimeout(86400000);

} catch (IOException e) {

e.printStackTrace();

}

try {

robot = new Robot();

} catch (AWTException e) {

e.printStackTrace();

}

}

public void changeServerPort(int serverPort){

if(this.serverPort==serverPort)return;

this.serverPort=serverPort;

try {

this.serverSocket.close();

} catch (Exception e) {}

try {

this.serverSocket = new ServerSocket(this.serverPort);

this.serverSocket.setSoTimeout(86400000);

} catch (Exception e) {

e.printStackTrace();

}

}

public int getServerPort(){

return this.serverPort;

}

public void run() {

while (true) {

try {

Socket socket = serverSocket.accept();

//读取操作信息:120,200,InputEvent.BUTTON1_DOWN_MASK 全部是int类型

InputStream is = socket.getInputStream();

int r;

String info = "";

while ((r = is.read()) != -1) {

info += "" + (char) r;

}

System.out.println(info);

is.close();

if (info != null) {

String s[] = info.trim().split(",");

if ("mouseClicked".equals(s[0].trim())) {//operateStr Model: mouseClicked,x,y,type

//由于加上单击事件后,鼠标按下并快速抬起 就设计到按下、抬起、单击 三个事件,将单击变为了双击 不合乎规范 所以 服务端并没有实现单击事件的监听,这里保留 不坐修改

int type = Integer.parseInt(s[s.length - 1].trim());

if (s.length == 4) {

int x = Integer.parseInt(s[1].trim());

int y = Integer.parseInt(s[2].trim());

robot.mouseMove(x, y);

robot.mousePress(type);

robot.mouseRelease(type);

System.out.println("ClientINFO:MOUSE move to "+x+","+y+" AND execute TYPE IS click "+type);

}

}else if("mousePressed".equals(s[0].trim())){//operateStr Model: mousePressed,x,y,type

int type = Integer.parseInt(s[s.length - 1].trim());

if (s.length == 4) {

int x = Integer.parseInt(s[1].trim());

int y = Integer.parseInt(s[2].trim());

robot.mouseMove(x, y);

robot.mousePress(type);

System.out.println("ClientINFO:MOUSE move to "+x+","+y+" AND execute TYPE IS press "+type);

}

}else if("mouseReleased".equals(s[0].trim())){//operateStr Model: mouseReleased,x,y,type

int type = Integer.parseInt(s[s.length - 1].trim());

if (s.length == 4) {

int x = Integer.parseInt(s[1].trim());

int y = Integer.parseInt(s[2].trim());

robot.mouseMove(x, y);

robot.mouseRelease(type);

System.out.println("ClientINFO:MOUSE move to "+x+","+y+" AND execute TYPE IS release "+type);

}

}else if("mouseDragged".equals(s[0].trim())){//operateStr Model: mouseDragged,x,y,type

if (s.length == 4) {

int x = Integer.parseInt(s[1].trim());

int y = Integer.parseInt(s[2].trim());

robot.mouseMove(x, y);

System.out.println("ClientINFO:MOUSE move to "+x+","+y );

}

}else if("mouseMoved".equals(s[0].trim())){

if (s.length == 3) {

int x = Integer.parseInt(s[1].trim());

int y = Integer.parseInt(s[2].trim());

robot.mouseMove(x, y);

System.out.println("ClientINFO:MOUSE move to "+x+","+y);

}

}else if("keyPress".equals(s[0].trim())){

if(s.length==2){

int keycode=Integer.parseInt(s[1]);

robot.keyPress(keycode);

}

}else if("keyRelease".equals(s[0].trim())){

if(s.length==2){

int keycode=Integer.parseInt(s[1]);

robot.keyRelease(keycode);

}

}else if("keyTyped".equals(s[0].trim())){

if(s.length==2){

int keycode=Integer.parseInt(s[1]);

robot.keyPress(keycode);

robot.keyRelease(keycode);

}

}

}

} catch (IOException e) {

System.out.println("error1");

}

}

}

}





/**

*监控端代码

*

*/



import java.awt.Dimension;

import java.awt.Image;

import java.awt.Toolkit;

import java.awt.event.KeyAdapter;

import java.awt.event.KeyEvent;

import java.awt.event.MouseAdapter;

import java.awt.event.MouseEvent;

import java.awt.event.MouseMotionAdapter;

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

import java.io.DataInputStream;

import java.io.IOException;

import java.io.OutputStream;

import java.net.Socket;

import java.net.UnknownHostException;

import java.util.concurrent.TimeUnit;

import java.util.zip.ZipInputStream;

import javax.imageio.ImageIO;

import javax.swing.*;

public class Client{

public static void main(String args[]) {

ServerGUI sendOrder=new ServerGUI("127.0.0.1", "实时操控");//被监控电脑的ip地址

WriteGUI catchScreen=new WriteGUI(sendOrder);

catchScreen.changePort(30009);//现在可以修改获取主机屏幕信息要访问的端口号

new Thread(catchScreen).start();//启动线程

}

}

/**

* @author LanXJ @doctime 2010-7-8

* 访问指定端口的服务,从服务器端读取图像流,生成(刷新)管理面板

* 默认访问的端口为DEFAULT_PORT=30011 端口,

* 可以通过changePort来改变访问端口,也可以通过getPort查看当前访问端口

* 实例化线程类时需要传入一个ServerGUI类型的辅助窗体对象

*/

class WriteGUI extends Thread {

public static final int DEFAULT_PORT=30011;

private int port;

private ServerGUI rec;

/**

* @param rec 辅助窗体对象,可通过实例化获得

*/

public WriteGUI(ServerGUI rec) {

this.port=WriteGUI.DEFAULT_PORT;

this.rec = rec;

}

public void changePort(int port){

this.port=port;

}

public int getPort(){

return this.port;

}

public void run() {

while (rec.getBoo()) {

System.out.println((System.currentTimeMillis()/1000)%24%60);

Socket socket = null;

try {

socket = new Socket(rec.getIP(), this.port);

DataInputStream dis = new DataInputStream(socket.getInputStream());

ZipInputStream zis = new ZipInputStream(dis);

Image image = null;

try {

zis.getNextEntry();// 读取下一个 ZIP 文件条目并将流定位到该条目数据的开始处

image = ImageIO.read(zis);// 把ZIP流转换为图片

rec.jlabel.setIcon(new ImageIcon(image));

rec.scroll.setViewportView(rec.jlabel);

rec.validate();

} catch (IOException ioe) {}

try{

// dis.close();

zis.close();

}catch (Exception e) {}

try {

TimeUnit.MILLISECONDS.sleep(50);// 接收图片间隔时间

} catch (InterruptedException ie) {

ie.printStackTrace();

}

} catch (IOException ioe) {

} finally {

try {

socket.close();

} catch (IOException e) {}

}

}

}

}

/**

* @author LanXJ @doctime 2010-7-8

* 访问指定主机的指定端口,向主机发送实例化线程类时传入的操控命令,实现对该主机的操控

* 默认访问服务端口为DEFAULT_PORT=30012 端口,主机IP为实例化线程类时传入的IP

* 可以通过changePort和changeIP来修改访问的端口和主机

* 也可以通过setOperateStr来设置需要发送的操控命令

* 需要注意的是,修改访问端口或主机必须在线程启动之前修改,否则修改无效

*/

class SendOperate extends Thread {

public static int DEFAULT_PORT=30012;

private String ip;

private int port;// 30012

private String operateStr;

public SendOperate(String ip, String operateStr) {

this.ip = ip;

this.port = SendOperate.DEFAULT_PORT;

this.operateStr = operateStr;

}

public void setOperateStr(String operateStr){

this.operateStr=operateStr;

}

public void changePort(int port){

this.port=port;

}

public boolean changeIP(String ip){

if(UtilServer.checkIp(ip)){

this.ip=ip;

return true;

}

return false;

}

public int getPort(){

return this.port;

}

public String getIP(){

return this.ip;

}

public void run() {

if(this.operateStr==null||this.operateStr.equals("")){

return;

}

// if(this.operateStr.trim().startsWith("mouseMoved")){

// return;

// }

try {

Socket socket = new Socket(this.ip, this.port);

OutputStream os = socket.getOutputStream();

os.write((this.operateStr).getBytes());

os.flush();

socket.close();

System.out.println("INFO: 【SendOperate】ip=" + this.ip + ",port=" + this.port + ",operateStr=/"" + this.operateStr + "/".");

} catch (UnknownHostException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}



}

/**

* @author LanXJ @doctime 2010-7-8

* 服务工具类

*/

class UtilServer{

public static boolean checkIp(String ip){

if(ip==null)return false;

String []dps=ip.split("//.");

if(dps.length!=4&&dps.length!=6)return false;

boolean isIp=true;

for (int i = 0; i < dps.length; i++) {

try {

int dp=Integer.parseInt(dps[i]);

if(dp>255||dp< 0){

throw new RuntimeException("error IP");

}

} catch (Exception e) {

isIp=false;

break;

}

}

return isIp;

}

}

/**

* @author LanXJ @doctime 2010-7-8

* serverManage的辅助窗体,内部事件封装了sendOperate的实现

*/

class ServerGUI extends JFrame {

private static final long serialVersionUID = 2273190419221320707L;

JLabel jlabel;

JScrollPane scroll;

private String ip;

private int port;

private boolean boo;

public boolean getBoo(){

return this.boo;

}

public int getPort(){

return this.port;

}

public void changePort(int port){

this.port=port;

}

public String getIP(){

return this.ip;

}

public boolean changeIP(String ip){

if(UtilServer.checkIp(ip)){

this.setTitle(this.getTitle().replace(this.ip, ip));

this.ip=ip;

return true;

}

return false;

}

protected ServerGUI(String IP, String sub) {

this.boo = true;

this.ip = IP;

this.port=SendOperate.DEFAULT_PORT;

this.setTitle("远程监控--IP:" + IP + "--主题:" + sub);

this.jlabel = new JLabel();

this.scroll = new JScrollPane();

this.scroll.add(this.jlabel);

scroll.addMouseListener(new MouseAdapter() {

/*public void mouseClicked(MouseEvent e) {// getMousePosition()

super.mouseClicked(e);

//由于加上单击事件后,鼠标按下并快速抬起 就设计到按下、抬起、单击 三个事件,将单击变为了双击

//所以不实现单击监听

int x = (int) e.getX() + (int) ServerGUI.this.scroll.getHorizontalScrollBar().getValue();

int y = (int) e.getY() + (int) ServerGUI.this.scroll.getVerticalScrollBar().getValue();

// int type = e.getModifiers();//e.BUTTON1_MASK 或 e.BUTTON2_MASK 或 e.BUTTON3_MASK

String operateStr ="mouseClicked,"+ x + "," + y + "," + e.getModifiers();



SendOperate sender=new SendOperate(ServerGUI.this.ip, (operateStr));

sender.changeIP(ServerGUI.this.ip);//同步ip

sender.changePort(ServerGUI.this.port);//同步port

sender.start();

}*/



public void mousePressed(MouseEvent e) {

super.mousePressed(e);

int x = (int) e.getX() + (int) ServerGUI.this.scroll.getHorizontalScrollBar().getValue();

int y = (int) e.getY() + (int) ServerGUI.this.scroll.getVerticalScrollBar().getValue();

// int type = e.getModifiers();//e.BUTTON1_MASK 或 e.BUTTON2_MASK 或 e.BUTTON3_MASK

String operateStr ="mousePressed,"+ x + "," + y + "," + e.getModifiers();



SendOperate sender=new SendOperate(ServerGUI.this.ip, (operateStr));

sender.changeIP(ServerGUI.this.ip);//同步ip

sender.changePort(ServerGUI.this.port);//同步port

sender.start();

}

@SuppressWarnings("static-access")

public void mouseReleased(MouseEvent e) {

super.mouseReleased(e);

int x = (int) e.getX() + (int) ServerGUI.this.scroll.getHorizontalScrollBar().getValue();

int y = (int) e.getY() + (int) ServerGUI.this.scroll.getVerticalScrollBar().getValue();

// int type = e.getModifiers();//e.BUTTON1_MASK 或 e.BUTTON2_MASK 或 e.BUTTON3_MASK

String operateStr ="mouseReleased,"+ x + "," + y + "," + e.getModifiers();



SendOperate sender=new SendOperate(ServerGUI.this.ip, (operateStr));

sender.changeIP(ServerGUI.this.ip);//同步ip

sender.changePort(ServerGUI.this.port);//同步port

sender.start();

}

});

scroll.addMouseMotionListener(new MouseMotionAdapter(){

public void mouseDragged(MouseEvent e) {

super.mouseDragged(e);

int x = (int) e.getX() + (int) ServerGUI.this.scroll.getHorizontalScrollBar().getValue();

int y = (int) e.getY() + (int) ServerGUI.this.scroll.getVerticalScrollBar().getValue();

String operateStr ="mouseDragged,"+ x + "," + y + "," + e.getModifiers();



SendOperate sender=new SendOperate(ServerGUI.this.ip, operateStr);

sender.changeIP(ServerGUI.this.ip);//同步ip

sender.changePort(ServerGUI.this.port);//同步port

sender.start();

}

public void mouseMoved(MouseEvent e) {

super.mouseMoved(e);

int x = (int) e.getX() + (int) ServerGUI.this.scroll.getHorizontalScrollBar().getValue();

int y = (int) e.getY() + (int) ServerGUI.this.scroll.getVerticalScrollBar().getValue();

String operateStr ="mouseMoved,"+ x + "," + y;



SendOperate sender=new SendOperate(ServerGUI.this.ip, (operateStr));

sender.changeIP(ServerGUI.this.ip);//同步ip

sender.changePort(ServerGUI.this.port);//同步port

sender.start();

}

});

this.addKeyListener(new KeyAdapter(){

public void keyPressed(KeyEvent e) {

super.keyPressed(e);

String operateStr ="keyPress,"+ e.getKeyCode();



SendOperate sender=new SendOperate(ServerGUI.this.ip, (operateStr));

sender.changeIP(ServerGUI.this.ip);//同步ip

sender.changePort(ServerGUI.this.port);//同步port

sender.start();

}

public void keyReleased(KeyEvent e) {

super.keyReleased(e);

String operateStr ="keyReleas,"+ e.getKeyCode();



SendOperate sender=new SendOperate(ServerGUI.this.ip, (operateStr));

sender.changeIP(ServerGUI.this.ip);//同步ip

sender.changePort(ServerGUI.this.port);//同步port

sender.start();

}

public void keyTyped(KeyEvent e) {

// super.keyTyped(e);

}

});

this.add(scroll);

this.setAlwaysOnTop(false);

Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();

this.setBounds(100, 75, (int) screenSize.getWidth() - 200, (int) screenSize.getHeight() - 150);

// this.setResizable(false);

this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);// 关闭窗体不做任何事

this.addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e) {

boo = false;

ServerGUI.this.dispose();

System.out.println("窗体关闭");

System.gc();

}

});

this.setVisible(true);

this.validate();

}

}






[b]该案例主要分为两个类文件,Server及其中的内部类,Client及其中的内部类。



大家可以参考。



如对Java远控比较感兴趣可以到我的网站上看一下



我们最近用Java开发的一款“黑天鹅远控”软件,并且为开源软件。


该案例为该软件中的一个功能点的源代码,并且已经整理成为单独的完善的案例。



我们的官方网站网址:


http://www.blackswansoft.com/



你可以在该网站上[b][b]下载


[/b]

[/b]
[b]“黑天鹅远控”软件。网站上发布了更多的java热点技术,欢迎大家参考。


[/b]

QQ:1037729010



Email:
blackswansoft@163.com


[/b]

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: