远程桌面监控系统java_java实现远程桌面监控

本文介绍了使用Java的Robot类创建一个简单的远程桌面监控程序。程序通过TCP连接,被监控端周期性截图并发送到服务器端,服务器端接收并显示图片。通过优化如使用UDP协议,可以提高效率。
摘要由CSDN通过智能技术生成

java里面的Robot类可以完成截图的功能,借助于这点,我尝试着做了一个简陋的桌面监控程序,运行了下,感觉速度还可以,还有很大的优化空间的,比如用udp协议取代tcp等。代码也写的不是很优雅,只在娱乐了。

实现原理其实很简单,在被监视者的机器上,运行一个线程,每隔一段时间就自动截图,并把截图压缩发送到指定的机器上;在监视机器上,也是运行一个线程,接收发送过来的图片包,解压,并绘制到当前的窗口上。这样就基本完成了。

public class Server extends Thread {

private Dimension screenSize;

private Rectangle rectangle;

private Robot robot;

public Server() {

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

rectangle = new Rectangle(screenSize);// 可以指定捕获屏幕区域

try {

robot = new Robot();

} catch (Exception e) {

e.printStackTrace();

System.out.println(e);

}

}

public void run() {

ZipOutputStream os = null;

Socket socket = null;

while (true) {

try {

socket = new Socket("192.168.1.100", 5001);// 连接远程IP

BufferedImage image = robot.createScreenCapture(rectangle);// 捕获制定屏幕矩形区域

os = new ZipOutputStream(socket.getOutputStream());// 加入压缩流

// os = new ZipOutputStream(new FileOutputStream("C:/1.zip"));

os.setLevel(9);

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

JPEGCodec.createJPEGEncoder(os).encode(image);// 图像编码成JPEG

os.close();

Thread.sleep(50);// 每秒20帧

} catch (Exception e) {

e.printStackTrace();

} finally {

if (os != null) {

try {

os.close();

} catch (Exception ioe) {

}

}

if (socket != null) {

try {

socket.close();

} catch (IOException e) {

}

}

}

}

}

public static void main(String[] args) {

new Server().start();

}

}

客户端:

public class Client extends JFrame {

private static final long serialVersionUID = 1L;

Dimension screenSize;

public Client() {

super();

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

this.setSize(800, 640);

Screen p = new Screen();

Container c = this.getContentPane();

c.setLayout(new BorderLayout());

c.add(p, SwingConstants.CENTER);

new Thread(p).start();

SwingUtilities.invokeLater(new Runnable(){

public void run() {

setVisible(true);

}});

}

public static void main(String[] args) {

new Client();

}

class Screen extends JPanel implements Runnable {

private static final long serialVersionUID = 1L;

private Image cimage;

public void run() {

ServerSocket ss = null;

try {

ss = new ServerSocket(5001);// 探听5001端口的连接

while (true) {

Socket s = null;

try {

s = ss.accept();

ZipInputStream zis = new ZipInputStream(s

.getInputStream());

zis.getNextEntry();

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

repaint();

} catch (Exception e) {

e.printStackTrace();

} finally {

if (s != null) {

try {

s.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

} catch (Exception e) {

} finally {

if (ss != null) {

try {

ss.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

public Screen() {

super();

this.setLayout(null);

}

public void paint(Graphics g) {

super.paint(g);

Graphics2D g2 = (Graphics2D) g;

g2.drawImage(cimage, 0, 0, null);

}

}

}

转帖:http://flypig.iteye.com/blog/383010

-------------------------------------------------------------------------------------------------------------------------------

1) RemoteClient

Connect to Server

0818b9ca8b590ca3270a3433284dd417.png

Collapse

|

Copy Code

System.out.println("Connecting to server ..........");

socket = new Socket(ip, port);

System.out.println("Connection Established.");

Capture Desktop Screen then Send it to the Server Periodically

In ScreenSpyerclass, Screenis captured using  createScreenCapture method inRobotclass and it accepts a Rectangleobject which carries screen dimension. If we try to send image object directly using serialization, it will fail because it does not implementSerializableinterface. That is why we have to wrap it using the ImageIconclass as shown below:

0818b9ca8b590ca3270a3433284dd417.png

Collapse

|

Copy Code

while(continueLoop){

//Capture screen

BufferedImage image = robot.createScreenCapture(rectangle);

/* I have to wrap BufferedImage with ImageIcon because

* BufferedImage class does not implement Serializable interface

*/

ImageIcon imageIcon = new ImageIcon(image);

//Send captured screen to the server

try {

System.out.println("before sending image");

oos.writeObject(imageIcon);

oos.reset(); //Clear ObjectOutputStream cache

System.out.println("New screenshot sent");

} catch (IOException ex) {

ex.printStackTrace();

}

//wait for 100ms to reduce network traffic

try{

Thread.sleep(100);

}catch(InterruptedException e){

e.printStackTrace();

}

}

Receive Server Events then call Robot Class Methods to Execute these Events

0818b9ca8b590ca3270a3433284dd417.png

Collapse

|

Copy Code

while(continueLoop){

//receive commands and respond accordingly

System.out.println("Waiting for command");

int command = scanner.nextInt();

System.out.println("New command: " + command);

switch(command){

case -1:

robot.mousePress(scanner.nextInt());

break;

case -2:

robot.mouseRelease(scanner.nextInt());

break;

case -3:

robot.keyPress(scanner.nextInt());

break;

case -4:

robot.keyRelease(scanner.nextInt());

break;

case -5:

robot.mouseMove(scanner.nextInt(), scanner.nextInt());

break;

}

}

2) RemoteServer

Wait for Clients Connections

0818b9ca8b590ca3270a3433284dd417.png

Collapse

|

Copy Code

//Listen to server port and accept clients connections

while(true){

Socket client = sc.accept();

System.out.println("New client Connected to the server");

//Per each client create a ClientHandler

new ClientHandler(client,desktop);

}

Receive Client Desktop Screenshots and Display them

0818b9ca8b590ca3270a3433284dd417.png

Collapse

|

Copy Code

while(continueLoop){

//Receive client screenshot and resize it to the current panel size

ImageIcon imageIcon = (ImageIcon) cObjectInputStream.readObject();

System.out.println("New image received");

Image image = imageIcon.getImage();

image = image.getScaledInstance

(cPanel.getWidth(),cPanel.getHeight(),Image.SCALE_FAST);

//Draw the received screenshot

Graphics graphics = cPanel.getGraphics();

graphics.drawImage(image, 0, 0, cPanel.getWidth(),cPanel.getHeight(),cPanel);

}

Handle Mouse and Key Events then Send them to the Client Program to Simulate them

In ClientCommandsSenderclass, when mouse is moved, x and y values are sent to the client but we have to take into consideration the size difference between clients' screen size and  server's panel size, that is why we have to multiply by a certain factor as shown in the following code:

0818b9ca8b590ca3270a3433284dd417.png

Collapse

|

Copy Code

public void mouseMoved(MouseEvent e) {

double xScale = clientScreenDim.getWidth()/cPanel.getWidth();

System.out.println("xScale: " + xScale);

double yScale = clientScreenDim.getHeight()/cPanel.getHeight();

System.out.println("yScale: " + yScale);

System.out.println("Mouse Moved");

writer.println(EnumCommands.MOVE_MOUSE.getAbbrev());

writer.println((int)(e.getX() * xScale));

writer.println((int)(e.getY() * yScale));

writer.flush();

}

public void mousePressed(MouseEvent e) {

System.out.println("Mouse Pressed");

writer.println(EnumCommands.PRESS_MOUSE.getAbbrev());

int button = e.getButton();

int xButton = 16;

if (button == 3) {

xButton = 4;

}

writer.println(xButton);

writer.flush();

}

public void mouseReleased(MouseEvent e) {

System.out.println("Mouse Released");

writer.println(EnumCommands.RELEASE_MOUSE.getAbbrev());

int button = e.getButton();

int xButton = 16;

if (button == 3) {

xButton = 4;

}

writer.println(xButton);

writer.flush();

}

public void keyPressed(KeyEvent e) {

System.out.println("Key Pressed");

writer.println(EnumCommands.PRESS_KEY.getAbbrev());

writer.println(e.getKeyCode());

writer.flush();

}

public void keyReleased(KeyEvent e) {

System.out.println("Mouse Released");

writer.println(EnumCommands.RELEASE_KEY.getAbbrev());

writer.println(e.getKeyCode());

writer.flush();

}

转帖:http://www.codeproject.com/KB/IP/RemoteAdminJava.aspx

package cn.com.origin.net; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public class Server { public Server() { } public void listen() throws IOException { ServerSocket server = new ServerSocket(8002); while (true) { try { Socket client = server.accept(); if (client != null) { ServerProcessor processor = new ServerProcessor(client); processor.start(); } } catch (Throwable e) { e.printStackTrace(); } } } public static void main(String[] args) throws IOException { Server s = new Server(); s.listen(); } } package cn.com.origin.net; import java.awt.AWTException; import java.awt.Rectangle; import java.awt.Robot; import java.awt.Toolkit; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import com.sun.image.codec.jpeg.ImageFormatException; import com.sun.image.codec.jpeg.JPEGCodec; public class ServerProcessor extends Thread { // private Socket client; public static final int SEND_IMAGE_SYMBOL = 0x00000000; // private InputStream is; private DataOutputStream dos; private Robot robot; private Rectangle rect; private BufferedImage bm; public ServerProcessor(Socket client) throws IOException, AWTException { // this.client = client; // is = client.getInputStream(); dos = new DataOutputStream(client.getOutputStream()); // bm = ImageIO.read(new File("E:\\Caokai\\001.png")); robot = new Robot(); rect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()); } public void run() { while (true) { try { bm = robot.createScreenCapture(rect); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ZipOutputStream zis = new ZipOutputStream(bos); zis.setLevel(9); zis.putNextEntry(new ZipEntry("ScreenCapture.jpg")); JPEGCodec.createJPEGEncoder(zis).encode(bm); // ImageIO.write(bm, "jpg", zis); zis.closeEntry(); bos.flush(); byte[] data = bos.toByteArray(); dos.write(SEND_IMAGE_SYMBOL); // System.out.println("Server - data.length = " + data.length); dos.writeInt(data.length); dos.write(data); dos.flush(); // 每秒2帧 Thread.sleep(500); } catch (ImageFormatException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); break; } catch (InterruptedException e) { e.printStackTrace(); } } } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值