现在在公司上班经常需要远程到项目进行一些问题的出来。大家知道qq远程再网络比较好的情况下还是可以的。 但是网络不是很给力的情况下大家应该也知道。经常用tv,也算比较好用,但是现在的高版本都是收费的,不买正版的5分钟就断一次所以基本没法用。再尝试多个后也都有缺点。周末没事自己就研究这怎么去写个可以实现远程控制的东东。
去网上找了些资料发现远程控制实现并不难。原理就如下。(完全是自己理解的写的不喜勿喷)
远程控制当然是一个控制端 一个被控制端。 被控制端降电脑屏幕截图发到控制端,(这时我们当然会快速的截图形成流畅即时效果)。控制端这时候要操作被控制端也就是把控制端的事件发送到被控制端,并且进行事件回放。完成控制操作
涉及知识点:
java socket编程
java io流操作
java 多线程
Robot类
个人感觉这些知识点差不多了都
大家理解下面的代码也可以下载我程序运行看看效果http://pan.baidu.com/s/1qXN0cYo
这里贴一下关键代码有助于大家理解:
被控制端: 开启服务
public static void main(String[] args) {
try {
new RemoteServer().setupServer(9090);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
控制端:
public static void main(String[] args) {
try {
Cntroller cn = new Cntroller();
cn.showui(); //显示页面链接
cn.conn2Server("localhost", 9090); //链接被控制端
cn.start();
} catch (Exception e) {
e.printStackTrace();
}
}
根据刚下表示的原理被控制端要完成2件事:
第一就是屏幕截屏发到控制端
package com.wfg.server;
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.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
/**
* 发送图片的线程
* @author wfg
*
*/
public class CaptureThread extends Thread{
private DataOutputStream dataOutputStream;
private Toolkit tk ;
private Dimension dm ;
private Rectangle rec;
private Robot robot ;
public CaptureThread(DataOutputStream dataOutputStream) throws AWTException {
this.dataOutputStream = dataOutputStream;
tk = Toolkit.getDefaultToolkit();
dm = tk.getScreenSize();
//根据屏幕设定图片的大小
rec = new Rectangle(0, 0, (int)dm.getWidth(), (int)dm.getHeight());
robot = new Robot();
}
@Override
public void run() {
while(true){
byte[] data = createCature();
try {
dataOutputStream.writeInt(data.length);
dataOutputStream.write(data);
dataOutputStream.flush();
try {
Thread.sleep(1000/20);
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("网络有问题,截屏失败");
}
}
}
private byte[] createCature() {
//获得一个屏幕的截图
BufferedImage bimage = robot.createScreenCapture(rec);
创建一段内存流
ByteArrayOutputStream byout = new ByteArrayOutputStream();
try {
//将图片数据写入内存流中
ImageIO.write(bimage, "jpg", byout);
} catch (IOException e) {
System.out.println("截屏图片写入内存流中出现异常");
e.printStackTrace();
}
return byout.toByteArray();
}
}
第二就是控制端的事件回放
package com.wfg.server;
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.io.ObjectInputStream;
public class EventReadThread extends Thread{
private ObjectInputStream objins;
public EventReadThread(ObjectInputStream objins) {
this.objins = objins;
}
@Override
public void run() {
while(true){
try {
Object eventobj = objins.readObject();
InputEvent e = (InputEvent) eventobj;
actionEvent(e);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
//回放事件的方法
private void actionEvent(InputEvent e){
Robot robot =null;
try {
robot = new Robot();
} catch (AWTException e1) {
e1.printStackTrace();
}
//是什么具体事件
if(e instanceof KeyEvent){
KeyEvent ke=(KeyEvent) e;
if(e.getID()==KeyEvent.KEY_PRESSED){
robot.keyPress(ke.getKeyCode());
}
if(e.getID()==KeyEvent.KEY_RELEASED){
robot.keyRelease(ke.getKeyCode());
}
}
if(e instanceof MouseEvent){
MouseEvent me = (MouseEvent)e;
int type = me.getID();
if(type==MouseEvent.MOUSE_PRESSED){ //按下
robot.mousePress(getMouseClick(me.getButton()));
}
if(type==MouseEvent.MOUSE_RELEASED){ //放开
robot.mouseRelease(getMouseClick(me.getButton()));
}
if(type==MouseEvent.MOUSE_MOVED) { //移动
robot.mouseMove(me.getX(), me.getY());
}
if(type==MouseEvent.MOUSE_DRAGGED) { //拖动
robot.mouseMove(me.getX(), me.getY());
}
if(type==MouseEvent.MOUSE_WHEEL) { //滑轮滚动
robot.mouseWheel(getMouseClick(me.getButton()));
}
}
}
//根据发送事的Mouse事件对象,转变为通用的Mouse按键代码
private int getMouseClick(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;
}
}
控制端完成的事情就是把事件发送到被控制端:
package com.wfg.client;
import java.awt.event.InputEvent;
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.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollBar;
import com.wfg.imag.MyJframe;
public class Cntroller extends Thread{
private ObjectOutputStream ous;
private DataInputStream ins;
private void showui(){
MyJframe jf = new MyJframe("dddd",ous);
addListener(jf); //添加监听
jf.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent arg0) {
System.out.println(arg0.getNewValue());
}
});
}
//2.连结服务器
private void conn2Server(String ip,int port)
throws Exception{
Socket sc=new Socket(ip,port);
//得到输入流,读取图片数据
ins=new DataInputStream(sc.getInputStream());
//得到输出流,发送事件对象
ous=new ObjectOutputStream(sc.getOutputStream());
//处理这两个流
}
@Override
public void run() {
try{
//读取图片数据
while(true){
int len=ins.readInt();//图片长度
byte[] data=new byte[len];
ins.readFully(data);
//将读到的数据生成为一个图标对象
ImageIcon ic=new ImageIcon(data);
//放到界面上.加到标签上
MyJframe.setImgLabel( ic,2);
}
}catch(Exception ef){
System.out.println("获取数据流出现异常");
ef.printStackTrace();
}
}
private void addListener(MyJframe jf ){
jf.addMouseListener(new MouseListener() {
@Override
public void mouseReleased(MouseEvent e) {
sentEvent(e);
}
@Override
public void mousePressed(MouseEvent e) {
sentEvent(e);
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseClicked(MouseEvent e) {
}
});
//鼠标移动事件
jf.addMouseMotionListener(new MouseMotionListener() {
@Override
public void mouseMoved(MouseEvent arg0) {
sentEvent(arg0);
}
@Override
public void mouseDragged(MouseEvent arg0) {
sentEvent(arg0);
}
});
//鼠标滑轮滑动事件
jf.addMouseWheelListener(new MouseWheelListener() {
@Override
public void mouseWheelMoved(MouseWheelEvent arg0) {
sentEvent(arg0);
}
});
//键盘事件
jf.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent arg0) {
sentEvent(arg0);
}
@Override
public void keyReleased(KeyEvent arg0) {
sentEvent(arg0);
}
@Override
public void keyPressed(KeyEvent arg0) {
sentEvent(arg0);
}
});
}
private void sentEvent(InputEvent e){
try {
ous.writeObject(e);
} catch (IOException e1) {
System.out.println("发送事件对象出现异常");
e1.printStackTrace();
}
}
public static void main(String[] args) {
try {
Cntroller cn = new Cntroller();
cn.showui();
cn.conn2Server("localhost", 9090);
cn.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
版权声明:本文为wufagang原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。