實現原理:
(1)被控端經過Robot截取桌面圖像經過socket通訊傳給主控端。
(2)主控端顯示被控端桌面,而且把基於被控端圖像上的鍵盤,鼠標事件經過socket通訊傳給被控端。
(3)被控端響應主控端的鼠標鍵盤事件。服務器
實現詳解:
(一)主控端和被控端經過UDP進行指令交互
/*-主控端向被控端發送指令-*/
String command = ...; //指令
InetAddress inet = ...; //被控端地址
int port = ...; //端口
byte sp[] = command.getBytes();
DatagramPacket packet = new DatagramPacket(sp,sp.length(),inet,port);
DatagramSocket sd = new DatagramSocket();
sd.send(packet);
/*-被控端接收指令-*/
DatagramSocket stockUDP = ...;
DatagramPacket packet = ...;
stockUDP.receive(packet);
String message=new String(packet.getData(),0,packet.getLength()); //獲得指令 socket
本程序中用到的指令
public static final String Command_Connection = "connection" ; //創建鏈接
public static final String Command_Disconnection = "disconnection";//斷開鏈接
public static final String Command_Screen = "screen"; //顯示被控端屏幕
public static final String Command_Control="control"; //創建控制套接this
(二)被控端向主控端傳遞圖像
/*-被控端獲取屏幕圖像-*/
Rectangle rect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());//全屏區域
Robot robot=new Robot();
BufferedImage image = robot.createScreenCapture(rect);
/*-開啓圖像傳送線程-*/
Socket socket = ...;
OutputStream out = socket.getOutputStream();
BufferedImage image ;
JPEGImageEncoder encoder =JPEGCodec.createJPEGEncoder(out);
......
public void run(){
while(true){
image = ...; //獲取屏幕圖像
encoder.encode(image); //發送圖像給主控端
Thread.sleep(Environment.IMAGE_GETTIME); //圖像採集時間間隔
}
}
/*-主控端圖像接收線程-*/
JPEGImageDecoder de = JPEGCodec.createJPEGDecoder(socket.getInputStream());
BufferedImage image = null ;
......
public void run(){
while(true){
image = de.decodeAsBufferedImage();
if (image != null) {
/*顯示圖像*/
}
}
}spa
(三)圖像顯示,鼠標,鍵盤監聽
/*-圖像顯示-*/
public class ControlledScreenPanel extends JPanel implements MouseMotionListener,
MouseListener,MouseWheelListener ,KeyListener{
private BufferedImage image ;線程
public void setBufferedImage(BufferedImage bi) { //更新圖像
image = bi;
Dimension d = new Dimension(image .getWidth(this),image .getHeight(this));
setPreferredSize(d);
revalidate();
repaint();
}code
public void paintComponent(Graphics g) { //繪製圖像
super.paintComponent(g);
Dimension d = getSize();
g.setColor(getBackground());
g.fillRect(0, 0, d.width, d.height);
if (image != null) {
g.drawImage(image , 0, 0, this);
}
}
}
/*-鼠標,鍵盤監聽-*/
private MainControlSocket control ; //發送鼠標,鍵盤事件到被控端
public void mouseDragged(MouseEvent e) {
control.sendControlledAction(e);
}對象
public void mouseMoved(MouseEvent e) {
control.sendControlledAction(e);
}事件
//--------------------------------------------------------------------------
public void mouseClicked(MouseEvent e) {
requestFocus();//單擊得到焦點
}get
public void mousePressed(MouseEvent e) { //鼠標按下
control.sendControlledAction(e);
}it
public void mouseReleased(MouseEvent e) { //鼠標釋放
control.sendControlledAction(e);
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
//--------------------------------------------------------------------------
public void mouseWheelMoved (MouseWheelEvent e){ //滑輪滾動
control.sendControlledAction(e);
}
//--------------------------------------------------------------------------
public void keyTyped(KeyEvent e) {}
public void keyPressed(KeyEvent e) { //鍵盤按下
control.sendControlledAction(e);
}
public void keyReleased(KeyEvent e) { //鍵盤釋放
control.sendControlledAction(e);
}
/*-發送鼠標,鍵盤事件到被控端-*/
class MainControlSocket {
private Socket socket = null;
private ObjectOutputStream out = null; //事件對象發送封裝
......
public void sendControlledAction(InputEvent event) {
try {
out.writeObject(event);
}
catch (IOException e) {
e.printStackTrace();
}
}
......
}
(三)被控端接收,響應鍵盤鼠標事件
private Socket socket = ...;
private ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
private Robot action = new Robot();
public void run(){
......
while(true){
Object obj = in.readObject(); //得到鼠標鍵盤事件
if (obj != null) {
handleEvent( (InputEvent) obj); //處理鼠標鍵盤事件
}
}
......
}
private void handleEvent(InputEvent event){
MouseEvent mevent = null ; //鼠標事件
MouseWheelEvent mwevent = null ;//鼠標滾動事件
KeyEvent kevent = null ; //鍵盤事件
int mousebuttonmask = -100; //鼠標按鍵
switch (event.getID()){
case MouseEvent.MOUSE_MOVED : //鼠標移動
mevent = ( MouseEvent )event ;
action.mouseMove( mevent.getX() , mevent.getY() );
break ;
case MouseEvent.MOUSE_PRESSED : //鼠標鍵按下
mevent = ( MouseEvent ) event;
action.mouseMove( mevent.getX() , mevent.getY() );
mousebuttonmask = getMouseClick( mevent.getButton() );
if(mousebuttonmask != -100)
action.mousePress(mousebuttonmask);
break;
case MouseEvent.MOUSE_RELEASED : //鼠標鍵鬆開
mevent = ( MouseEvent ) event;
action.mouseMove( mevent.getX() , mevent.getY() );
mousebuttonmask = getMouseClick( mevent.getButton() );//取得鼠標按鍵
if(mousebuttonmask != -100)
action.mouseRelease( mousebuttonmask );
break ;
case MouseEvent.MOUSE_WHEEL : //鼠標滾動
mwevent = ( MouseWheelEvent ) event ;
action.mouseWheel(mwevent.getWheelRotation());
break ;
case MouseEvent.MOUSE_DRAGGED : //鼠標拖拽
mevent = ( MouseEvent ) event ;
action.mouseMove( mevent.getX(), mevent.getY() );
break ;
case KeyEvent.KEY_PRESSED : //按鍵
kevent = ( KeyEvent ) event;
action.keyPress( kevent.getKeyCode() );
break ;
case KeyEvent.KEY_RELEASED : //鬆鍵
kevent= ( KeyEvent ) event ;
action.keyRelease( kevent.getKeyCode() );
break ;
default: break ;
}
}
private int getMouseClick(int button) { //取得鼠標按鍵 if (button == MouseEvent.BUTTON1) //左鍵 ,中間鍵爲BUTTON2 return InputEvent.BUTTON1_MASK; if (button == MouseEvent.BUTTON3) //右鍵 return InputEvent.BUTTON3_MASK; return -100; } ...... }