遠程控制(RemoteControl)
遠程控制(RemoteControl)擁有控制端和被控端雙方...2
遠程控制(RemoteControl)的核心技術(shù) 5
遠程控制(RemoteControl)擁有控制端和被控端雙方。
控制方通過(guò)請求,取得對遠端的操作,實(shí)現遠端的事件回放功能,同時(shí),應該看得到遠端桌面的畫(huà)面。
而被控方必須在建立ServerSocket之后進(jìn)行對外來(lái)請求的鑒聽(tīng)。如下圖,
利用JAVA.AWT.ROBOT類(lèi),實(shí)現在遠端的回放功能
例子:// Robot使用示例
import java.awt.Toolkit;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
publicclass RobotTest {
publicstaticvoid main(String[]args)throws Exception {
// 創(chuàng )建一個(gè)機器人對象
java.awt.Robot robot = new java.awt.Robot();
//當前屏幕大小
Toolkit tk = java.awt.Toolkit.getDefaultToolkit();
java.awt.Dimension dm = tk.getScreenSize();
//計算屏幕中心點(diǎn)
int x = (int) dm.getWidth() / 2;
int y = (int) dm.getHeight() / 2;
// 將鼠標移動(dòng)到屏幕中心
robot.mouseMove(x, y);
// 按下鼠標左鍵
robot.mousePress(InputEvent.BUTTON1_MASK);
// 松開(kāi)鼠標左鍵
robot.mouseRelease(InputEvent.BUTTON1_MASK);
// 模擬按下回車(chē)鍵
robot.keyPress(KeyEvent.VK_ENTER);
// 模擬放松回車(chē)鍵
robot.keyRelease(KeyEvent.VK_ENTER);
// 按下SHIFT鍵
robot.keyPress(KeyEvent.VK_SHIFT);
for (int i = 0; i < 10; i++) {
// 在屏幕上打字
robot.keyPress('A' + i);
robot.keyRelease('A' + i);
Thread.sleep(500);
}
// 松開(kāi)SHIFT鍵
robot.keyRelease(KeyEvent.VK_SHIFT);
for (int i = 0; i < 11; i++) {
// 刪除操作
robot.keyPress(KeyEvent.VK_BACK_SPACE);
robot.keyRelease(KeyEvent.VK_BACK_SPACE);
Thread.sleep(500);
}
}
}
同樣利用ROBOT里的createScreenCapture()方法進(jìn)行畫(huà)面的捕獲。
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import javax.swing.*;
publicclass ScreenTest {
// 截屏測試
publicstaticvoid main(String[] args)throws Exception {
//控制臺標題
JFrame jf = new JFrame("控制臺");
//控制臺大小
jf.setSize(500, 400);
//imag_lab用于存放畫(huà)面
JLabel imag_lab = new JLabel();
jf.add(imag_lab);
//設置控制臺可見(jiàn)
jf.setVisible(true);
//控制臺置頂
jf.setAlwaysOnTop(true);
//控制臺退出模式
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
java.awt.Dimension d =jf.size();
java.awt.Graphics g = jf.getGraphics();
//當前屏幕大小
Toolkit tk = java.awt.Toolkit.getDefaultToolkit();
java.awt.Dimension dm =tk.getScreenSize();
//創(chuàng )建Robot對象
java.awt.Robot robot = new java.awt.Robot();
for (int i = 0; i < 1000; i++) {
//截取指定大小的屏幕區域
Rectangle rec = new Rectangle(0, 0, (int) dm.getWidth(), (int) dm
.getHeight());
BufferedImage bimage = robot.createScreenCapture(rec);
//將圖片轉為小圖片
BufferedImage littleImage =resize(bimage,jf.getWidth(),jf
.getHeight());
//將圖片保存到文件中
FileOutputStream fous =new FileOutputStream("screenImg”+i+”.jpeg");
// javax.imageio.ImageIO.write(littleImage, "jpeg", fous);
fous.flush();
fous.close();
//將小圖片顯示到界面上
imag_lab.setIcon(new javax.swing.ImageIcon(littleImage));
Thread.sleep(50);
}
}
privatestatic BufferedImage resize(BufferedImage img,int newW,int newH) {
int w = img.getWidth();
int h = img.getHeight();
BufferedImage dimg = new BufferedImage(newW, newH, img.getType());
Graphics2D g = dimg.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(img, 0, 0, newW, newH, 0, 0, w, h,null);
g.dispose();
return dimg;
}
}
利用JAVA Socket編程,使控制端與被控端之間建立數據傳輸的數據流通道。
例子:
(遠端)ServerSocketss =new ServerSocket(PORT);
Socket client = ss.accept();
(近端)Socket s=new Socket(IP,PORT);
注:Socket有對應的輸入輸出(InputStream、 OutputStream)流對象。
將控制端所偵聽(tīng)到的事件封裝成InputEvent類(lèi),用對像輸入出流,往遠端寫(xiě)出去。
privatevoidsendEventObject(java.awt.event.InputEventevent){
try{
//將事件對象發(fā)送到被控制端
ous.writeObject(event);
}catch(Exception ef){
ef.printStackTrace();
}
}
在遠端,每隔一段一定的時(shí)間,將從桌面捕獲的畫(huà)面圖片,用javax.io.ImagIO轉成一個(gè)字節數組,從而將每一個(gè)畫(huà)面的數據量大小,以及數據用數據輸出流往控制端發(fā)送。
相關(guān)代碼:
publicvoid run(){
//截圖,發(fā)送
try{
while(true){
byte[] data=createImage();
//發(fā)送:
//1.先寫(xiě)一個(gè)int ,代表圖片數據長(cháng)度
dous.writeInt(data.length);
//2.寫(xiě)入圖片字節數據
dous.write(data);
dous.flush();
Thread.sleep(1000/20);
}
}catch(SocketExceptionef){
// ef.printStackTrace();
rs.destroy();
thrownew MyException("客戶(hù)端SOCKET已斷開(kāi)連接,無(wú)法發(fā)送圖片信息。。");
} catch(InterruptedException e) {
//TODO Auto-generatedcatch block
rs.destroy();
thrownew MyException("客戶(hù)端已中斷連接,無(wú)法發(fā)送圖片信息。。");
} catch (IOException e) {
//TODO Auto-generatedcatch block
rs.destroy();
thrownew MyException("客戶(hù)端輸入輸出流中斷,無(wú)法發(fā)送圖片信息。。");
} catch (Exception e) {
//TODO Auto-generatedcatch block
rs.destroy();
thrownew MyException("客戶(hù)端已斷開(kāi)連接,無(wú)法發(fā)送圖片信息。。");
}
}
//取得一張屏幕圖片,轉成字節數組返回
privatebyte[] createImage()throws Exception{
java.awt.Robot robot=new java.awt.Robot();
java.awt.Toolkit tk=java.awt.Toolkit.getDefaultToolkit();
java.awt.Dimensiondm=tk.getScreenSize();
//設定區域的大小
Rectangle rt=new Rectangle(0,0,dm.width,dm.height);
//取得指定大小的一張圖片
BufferedImage image=robot.createScreenCapture(rt);
//創(chuàng )建一段內存流
java.io.ByteArrayOutputStreamtemB=newByteArrayOutputStream();
//將圖片數據寫(xiě)入內存流中
javax.imageio.ImageIO.write(image,"jpeg", temB);
//做為字節數組返回
byte[] data=temB.toByteArray();
return data;
}
在控制端,實(shí)現對所有事件(Mouse、Key)的偵聽(tīng),將所有事件封裝在InputEvent類(lèi),并用對像輸出流ObjectOutputStream發(fā)送到遠端。同時(shí),控制端為一個(gè)線(xiàn)程,不斷地執行run()方法,將接收到的畫(huà)面數據(按遠端轉成字節數據的逆過(guò)程)轉成圖片,并在控制端顯示。
控制端代碼(在包c(diǎn)om.zzw.client里有三個(gè)類(lèi),代碼分別如下)
package com.zzw.client;
importjava.awt.FlowLayout;
import java.awt.event.*;
import javax.swing.*;
importjava.net.InetAddress;
importjava.net.UnknownHostException;
public class Client extends JFrame {
/**
* @param args
*/
public JTextField iptf =new JTextField(10);
public JTextField porttf =new JTextField(3);
public JButton jb1 = new JButton("連接");
public JButton jb2 = new JButton("斷開(kāi)");
public void launch(){
this.setTitle("遠程控制客戶(hù)端---連接窗口");
this.setLocation(300, 200);
this.setSize(300, 100);
this.setAlwaysOnTop(true);
JLayeredPane jlp =new JLayeredPane();
jlp.setLayout(new FlowLayout());
jlp.add(new JLabel("遠程IP地址:"));
iptf.setText("127.0.0.1");
porttf.setText("8888");
jlp.add(iptf);
jlp.add(new JLabel("端口:"));
jlp.add(porttf);
jb1.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e) {
try {
ClientDealObject.connect(iptf.getText(),Integer.parseInt(porttf.getText().trim()));
} catch (NumberFormatException e1) {
//端口號格式輸入出錯
JOptionPane.showMessageDialog(null,"IP地址或端口號輸入出錯,無(wú)法取得連接。。","提示",JOptionPane.ERROR_MESSAGE);
System.exit(0);
destroy();
//
} catch (MyException e1) {
// JOptionPane.showMessageDialog(null,e1.info,"提示",JOptionPane.ERROR_MESSAGE);
//
}catch(Exception ed){
// "遠程不允許被控,無(wú)法取得連接。。
JOptionPane.showMessageDialog(null,"遠程不允許被控,無(wú)法取得連接。。","提示",JOptionPane.ERROR_MESSAGE);
System.exit(0);
destroy();
}
//連接成功
}
});
jb2.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e) {
JOptionPane.showMessageDialog(null, "斷開(kāi)控制端窗口","提示",JOptionPane.INFORMATION_MESSAGE);
System.exit(0);
destroy();
}
});
jlp.add(jb1);
jlp.add(jb2);
this.setLayeredPane(jlp);
this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e) {
// 關(guān)閉窗口
JOptionPane.showMessageDialog(null, "關(guān)閉連接窗口","提示",JOptionPane.INFORMATION_MESSAGE);
System.exit(0);
}
});
this.setVisible(true);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
// new RemoteControlLoginFrame().getLocalIP();
new Client().launch();
}
public String getLocalIP(){
String ipstr = "";
InetAddress ip = null;
try {
ip = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ipstr = ip.toString();
ipstr = ipstr.substring(ipstr.indexOf("/")+1);
System.out.println(ipstr);
return ipstr;
}
public void destroy(){
this.destroy();
}
}
///////
package com.zzw.client;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Image;
importjava.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
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.awt.image.BufferedImage;
importjava.io.ByteArrayInputStream;
importjava.io.DataInputStream;
importjava.io.ObjectOutputStream;
importjavax.imageio.ImageIO;
importjavax.swing.ImageIcon;
importjavax.swing.JLayeredPane;
public class ClientDealObject extends Thread{
public int x,y;
private java.io.DataInputStream dins;
private java.io.ObjectOutputStream ous;
private javax.swing.JLabel la_image=new javax.swing.JLabel();
public void showUI(){
javax.swing.JFrame frame=new javax.swing.JFrame("遠程控制");
frame.setSize(800,600);
frame.setResizable(false);
la_image.setSize(800, 600);
JLayeredPane jlp = new JLayeredPane();
jlp.add(la_image);
frame.setLayeredPane(jlp);
frame.setVisible(true);
frame.setDefaultCloseOperation(3);
frame.setAlwaysOnTop(true);
frame.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e) {
sendEventObject(e);
}
@Override
public void keyReleased(KeyEvent e) {
sendEventObject(e);
}
@Override
public void keyTyped(KeyEvent e) {
}
});
frame.addMouseWheelListener(new MouseWheelListener(){
public void mouseWheelMoved(MouseWheelEvent e) {
sendEventObject(e);
}
});
frame.addMouseMotionListener(new MouseMotionListener(){
public void mouseDragged(MouseEvent e) {
sendEventObject(e);
}
public void mouseMoved(MouseEvent e) {
sendEventObject(e);
}
});
frame.addMouseListener(new MouseListener(){
public void mouseClicked(MouseEvent e) {
sendEventObject(e);
}
public void mouseEntered(MouseEvent e) {
sendEventObject(e);
}
public void mouseExited(MouseEvent e) {
sendEventObject(e);
}
public void mousePressed(MouseEvent e) {
sendEventObject(e);
}
public void mouseReleased(MouseEvent e) {
sendEventObject(e);
}
});
}
private void conn2Server(String ip,int port)
throws MyException,Exception{
java.net.Socket sc=new java.net.Socket(ip,port);
dins=newDataInputStream(sc.getInputStream());
ous=newObjectOutputStream(sc.getOutputStream());
if(dins==null||ous==null)throw newMyException("遠程控制不接受或未接受被控制。。。");
}
//發(fā)送事件對象到被控制端
private void sendEventObject(java.awt.event.InputEvent event){
try{
ous.writeObject(event);
}catch(Exception ef){
ef.printStackTrace();
}
}
public void run(){
try{
while(true){
int len=dins.readInt();
byte[] data=new byte[len];
dins.readFully(data);
ByteArrayInputStream bins=newByteArrayInputStream(data);
BufferedImage image= ImageIO.read(bins);
javax.swing.ImageIcon ic=new ImageIcon(image);
Image img = ic.getImage();
Toolkit tk = Toolkit.getDefaultToolkit() ;
Dimension d =tk.getScreenSize();
int w = d.width;
int h =d.height;
BufferedImage bi = resize(img,800,600);
la_image.setIcon(new ImageIcon(bi));
la_image.repaint();//銷(xiāo)掉以前畫(huà)的背景
}
}catch(Exception ef){
System.out.println("網(wǎng)絡(luò )故障:無(wú)法讀出遠程圖片數據。。。");
ef.printStackTrace();
}
}
private static BufferedImage resize(Image img, int newW, intnewH) {
int w = img.getWidth(null);
int h = img.getHeight(null);
BufferedImage dimg = new BufferedImage(newW, newH,BufferedImage.TYPE_INT_BGR);
Graphics2D g = dimg.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(img, 0, 0, newW, newH, 0, 0, w, h, null);
g.dispose();
return dimg;
}
public static void main(String[] args)
throws Exception{
}
public static void connect(String ip,intport) throws Exception{
ClientDealObject ct=newClientDealObject();
ct.showUI();
ct.conn2Server(ip,port);
ct.start();
}
}
package com.zzw.client;
import javax.swing.JOptionPane;
public classMyException extendsRuntimeException {
public String info= "";
public MyException(String info){
this.info = info;
System.out.println(info);
JOptionPane.showMessageDialog(null, this.info,"提示",JOptionPane.ERROR_MESSAGE);
}
}
---------------developed it in the year of 2010 by zzw--僅供學(xué)習使用--------------------------------------------------
聯(lián)系客服