使用java作屏幕監控案例源代碼

使用Java開發的屏幕監控案例源代碼,能夠實現鼠標,鍵盤的監聽,能夠經過該案例實現
屏幕監控他人電腦,和QQ的遠程協助相似。

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;

/**
 *使用Java截屏工具,不停的截取當前屏幕圖片,圖片不需保存直接以流的形式發送的監控端電腦上,並顯示出來
  *控制端的鼠標和鍵盤的操做再發送的被控端而且執行從而實現屏幕監控
  *能夠達到用一臺電腦徹底控制另一臺電腦
  */

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();

	}

}
屏幕監視設計思想:http://www.blackswansoft.com/songhaikang/article/20110221105156640.html  更多的優秀Java案例:請到http://www.blackswansoft.com 網站上參考。
相關文章
相關標籤/搜索