java實(shí)現(xiàn)遠(yuǎn)程桌面的實(shí)例代碼
控制端將鼠標(biāo)事件傳遞到服務(wù)端
服務(wù)端拿到鼠標(biāo)事件之后傳輸?shù)娇蛻舳?/strong>
客戶端拿到鼠標(biāo)事件之后,通過robot類即可完成,并且截屏將圖片發(fā)給服務(wù)器,服務(wù)器再發(fā)給控制端
被我簡(jiǎn)化之后得到
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
//先介紹一下robot類的簡(jiǎn)單使用 import java.awt.awtexception; import java.awt.robot; import java.awt.event.inputevent; /** * 使用robot * @author 啞元 * */ public class robottest { public static void main(string[] args) throws awtexception { robot r = new robot(); r.mousemove( 300 , 500 ); //鼠標(biāo)移動(dòng) r.mousepress(inputevent.button1_mask ); //鼠標(biāo)按下 r.mouserelease(inputevent.button1_mask); //鼠標(biāo)松開 r.keypress(( int ) 'a' ); //鍵盤按下 (int)'a'表示將a轉(zhuǎn)換成鍵盤對(duì)應(yīng)的key r.keyrelease(( int ) 'a' ); //鍵盤松開 } } //屏幕抓取 import java.awt.awtexception; import java.awt.rectangle; import java.awt.robot; import java.awt.image.bufferedimage; import javax.swing.imageicon; import javax.swing.jframe; import javax.swing.jlabel; import javax.swing.windowconstants; /** * 抓取本地桌面圖片 * @author 啞元 * */ public class screentest { public static void main(string[] args) throws awtexception, interruptedexception { robot robot = new robot(); jframe jframe = new jframe(); jframe.setsize( 1200 , 700 ); jlabel label = new jlabel(); jframe.add(label); //四個(gè)參數(shù)x y width height jframe.setvisible( true ); jframe.setdefaultcloseoperation(windowconstants.exit_on_close ); //構(gòu)建一個(gè)死循環(huán)動(dòng)態(tài)截取 while ( true ){ bufferedimage image = robot.createscreencapture( new rectangle( 0 , 0 , 1366 , 768 )); //截取屏幕 label.seticon( new imageicon(image)); thread.sleep( 50 ); } } } |
//遠(yuǎn)程控制原理講解
//分為server端和client端,
//原本server端只作為轉(zhuǎn)發(fā),作為演示,就不寫轉(zhuǎn)發(fā)
//也就是client端控制server端e
/**
* 這里我采用的是,在client端也就是操控端,接收到server端發(fā)送過來(lái)的screen之后,然后發(fā)送鼠標(biāo)事件過去
* 然后再用robot處理
* 傳輸方式用socket+io即可處理
* 屏幕截取和圖片壓縮采用了robot的屏幕截取功能和jdk自帶的圖片編碼器,將其轉(zhuǎn)換成一個(gè)字節(jié)數(shù)組
* 發(fā)送給server端之后,robot通過io+socket可以直接拿到object對(duì)象,強(qiáng)制轉(zhuǎn)換成inputevent(keyevent和mouseevent都繼承)之后
* 通過判斷event類型,分別處理即可,這里在服務(wù)端需要用到兩個(gè)線程,一個(gè)是屏幕截取和發(fā)送給客戶端,一個(gè)是用來(lái)監(jiān)聽客戶端
* 傳遞過來(lái)的事件
*/
//下面是具體實(shí)現(xiàn)代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
|
//server主程 import java.awt.awtexception; import java.awt.event; import java.awt.robot; import java.awt.event.inputevent; import java.awt.event.keyevent; import java.awt.event.mouseevent; import java.io.dataoutputstream; import java.io.ioexception; import java.io.objectinputstream; import java.net.serversocket; import java.net.socket; /** * 服務(wù)端 * @author 啞元 * */ public class server { public static void main(string[] args) throws ioexception { serversocket server = new serversocket( 80 ); system.out.println( "服務(wù)器已經(jīng)正常啟動(dòng)" ); socket socket = server.accept(); //等待接收請(qǐng)求,阻塞方法 system.out.println( "有客戶端連接" ); dataoutputstream dos = new dataoutputstream(socket.getoutputstream()); //將客戶端與服務(wù)器端鏈接的輸出流交個(gè)imagethread處理 imagethread imagethread = new imagethread(dos); new thread(imagethread).start(); new thread( new eventthread( new objectinputstream(socket.getinputstream()))).start(); } } /** * 用來(lái)處理接收過來(lái)的鼠標(biāo)事件或者鍵盤事件 */ class eventthread implements runnable{ private objectinputstream ois; private robot robot; public eventthread(objectinputstream ois) { this .ois = ois; } @override public void run() { try { robot = new robot(); while ( true ){ inputevent event = (inputevent)ois.readobject(); //得知由客戶端傳遞過來(lái)的是一個(gè)object對(duì)象 actionevent(event); //處理事件 } } catch (awtexception e) { e.printstacktrace(); } catch (classnotfoundexception e) { e.printstacktrace(); } catch (ioexception e) { e.printstacktrace(); } finally { try { ois.close(); } catch (ioexception e) { e.printstacktrace(); } } } /** * 事件處理,用來(lái)判斷事件類型,并用robot類執(zhí)行 * @param event */ public void actionevent(inputevent event){ system.out.println(event); if (event instanceof keyevent){ keyevent e = (keyevent)event; int type = e.getid(); //拿到事件類型 if (type==event.key_press){ robot.keypress(e.getkeycode()); } else if (type == event.key_release){ robot.keyrelease(e.getkeycode()); } } else if (event instanceof mouseevent){ mouseevent e = (mouseevent)event; int type = e.getid(); if (type == event.mouse_move){ robot.mousemove(e.getx(),e.gety()); } else if (type == event.mouse_down){ robot.mousepress(getmousekey(type)); } else if (type == event.mouse_up){ robot.mouserelease(getmousekey(type)); } else if (type == event.mouse_drag){ robot.mousemove(e.getx(), e.gety()); //鼠標(biāo)拖動(dòng) } } } /** * 返回鼠標(biāo)的真正事件,鼠標(biāo)時(shí)間不能直接處理,需要進(jìn)過轉(zhuǎn)換 * @return */ public int getmousekey( int button){ if (button == mouseevent.button1){ //鼠標(biāo)左鍵 return inputevent.button1_mask; } else if (button == mouseevent.button2){ //鼠標(biāo)右鍵 return inputevent.button2_mask; } else if (button == mouseevent.button3){ //滾輪 return inputevent.button3_mask; } else { return 0 ; } } } //屏幕截取器和發(fā)送器,這里需要拿到socket的out流 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.bytearrayoutputstream; import java.io.dataoutputstream; import java.io.ioexception; import com.sun.image.codec.jpeg.*; /** * 用來(lái)將圖片數(shù)據(jù)發(fā)送 * @author 啞元 * */ public class imagethread implements runnable{ dataoutputstream dos = null ; //數(shù)據(jù)輸出流 public imagethread(dataoutputstream dos){ this .dos = dos; } @override public void run() { try { robot robot = new robot(); //截取整個(gè)屏幕 dimension dimension = toolkit.getdefaulttoolkit().getscreensize(); /* int width = (int)dimension.getwidth(); int height = (int)dimension.getwidth(); rectangle rec = new rectangle(0,0,width,height); */ rectangle rec = new rectangle(dimension); bufferedimage image; byte imagebytes[]; while(true){ image = robot.createscreencapture(rec); imagebytes = getimagebytes(image); dos.writeint(imagebytes.length); dos.write(imagebytes); dos.flush(); thread.sleep(50); //線程睡眠 } } catch (awtexception e) { e.printstacktrace(); } catch (imageformatexception e) { e.printstacktrace(); } catch (ioexception e) { e.printstacktrace(); } catch (interruptedexception e) { e.printstacktrace(); }finally{ try { if(dos!= null) dos.close(); } catch (ioexception e) { e.printstacktrace(); } } } /** * 壓縮圖片 * @param 需要壓縮的圖片 * @return 壓縮后的byte數(shù)組 * @throws ioexception * @throws imageformatexception */ public byte[] getimagebytes(bufferedimage image) throws imageformatexception, ioexception{ bytearrayoutputstream baos = new bytearrayoutputstream(); //壓縮器壓縮,先拿到存放到byte輸出流中 jpegimageencoder jpegd = jpegcodec.createjpegencoder(baos); //將iamge壓縮 jpegd.encode(image); //轉(zhuǎn)換成byte數(shù)組 return baos.tobytearray(); } } -------------------------------------------------------------------------------------- //client端,用來(lái)接收creen圖片和發(fā)送鼠標(biāo)事件 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.io.datainputstream; import java.io.ioexception; import java.io.objectoutputstream; import java.net.socket; import java.net.unknownhostexception; import javax.swing.imageicon; import javax.swing.jframe; import javax.swing.jlabel; import javax.swing.jpanel; import javax.swing.jscrollpane; import javax.swing.windowconstants; /** * 客戶端 * @author 啞元 * */ public class client { public static void main(string args[]) throws unknownhostexception, ioexception{ socket s = new socket("127.0.0.1",80); datainputstream dis = new datainputstream(s.getinputstream()); objectoutputstream oos = new objectoutputstream(s.getoutputstream()); clientwindow cw = new clientwindow(oos); byte[] imagebytes; while(true){ imagebytes = new byte[dis.readint()]; //先拿到傳過來(lái)的數(shù)組長(zhǎng)度 dis.readfully(imagebytes); //所有的數(shù)據(jù)存放到byte中 cw.repainimage(imagebytes); } } } /** * 客戶端窗體 * @author 啞元 * */ class clientwindow extends jframe{ private objectoutputstream oos; private jlabel label; //重寫背景圖片方法 public void repainimage( byte [] imagebytes){ label.seticon( new imageicon(imagebytes)); this .repaint(); } public clientwindow(objectoutputstream oos){ this .oos = oos; this .settitle( "遠(yuǎn)程控制程序" ); label = new jlabel(); jpanel p = new jpanel(); p.add(label); jscrollpane scroll = new jscrollpane(p); //給p面板添加滾動(dòng)條 this .add(scroll); this .setsize( 1024 , 768 ); this .setdefaultcloseoperation(windowconstants.exit_on_close); this .setvisible( true ); this .addkeylistener( new keylistener() { @override public void keytyped(keyevent e) { // todo auto-generated method stub } @override public void keyreleased(keyevent e) { sendevent(e); } @override public void keypressed(keyevent e) { sendevent(e); } }); label.addmouselistener( new mouselistener() { @override public void mousereleased(mouseevent e) { sendevent(e); } @override public void mousepressed(mouseevent e) { sendevent(e); } @override public void mouseclicked(mouseevent e) { sendevent(e); } @override public void mouseentered(mouseevent e) { // todo auto-generated method stub } @override public void mouseexited(mouseevent e) { // todo auto-generated method stub } }); } public void sendevent(inputevent event){ try { oos.writeobject(event); } catch (ioexception e) { e.printstacktrace(); } } } |
以上這篇java實(shí)現(xiàn)遠(yuǎn)程桌面的實(shí)例代碼就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持服務(wù)器之家。
原文鏈接:http://blog.csdn.net/qq_25956141/article/details/78621983