控制端将鼠标事件传递到服务端
服务端拿到鼠标事件之后传输到客户端
客户端拿到鼠标事件之后,通过robot类即可完成,并且截屏将图片发给服务器,服务器再发给控制端
被我简化之后得到
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类的简单使用 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 ); //鼠标移动 r.mousepress(inputevent.button1_mask ); //鼠标按下 r.mouserelease(inputevent.button1_mask); //鼠标松开 r.keypress(( int ) 'a' ); //键盘按下 (int)'a'表示将a转换成键盘对应的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); //四个参数x y width height jframe.setvisible( true ); jframe.setdefaultcloseoperation(windowconstants.exit_on_close ); //构建一个死循环动态截取 while ( true ){ bufferedimage image = robot.createscreencapture( new rectangle( 0 , 0 , 1366 , 768 )); //截取屏幕 label.seticon( new imageicon(image)); thread.sleep( 50 ); } } } |
//远程控制原理讲解
//分为server端和client端,
//原本server端只作为转发,作为演示,就不写转发
//也就是client端控制server端e
/**
* 这里我采用的是,在client端也就是操控端,接收到server端发送过来的screen之后,然后发送鼠标事件过去
* 然后再用robot处理
* 传输方式用socket+io即可处理
* 屏幕截取和图片压缩采用了robot的屏幕截取功能和jdk自带的图片编码器,将其转换成一个字节数组
* 发送给server端之后,robot通过io+socket可以直接拿到object对象,强制转换成inputevent(keyevent和mouseevent都继承)之后
* 通过判断event类型,分别处理即可,这里在服务端需要用到两个线程,一个是屏幕截取和发送给客户端,一个是用来监听客户端
* 传递过来的事件
*/
//下面是具体实现代码
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; /** * 服务端 * @author 哑元 * */ public class server { public static void main(string[] args) throws ioexception { serversocket server = new serversocket( 80 ); system.out.println( "服务器已经正常启动" ); socket socket = server.accept(); //等待接收请求,阻塞方法 system.out.println( "有客户端连接" ); dataoutputstream dos = new dataoutputstream(socket.getoutputstream()); //将客户端与服务器端链接的输出流交个imagethread处理 imagethread imagethread = new imagethread(dos); new thread(imagethread).start(); new thread( new eventthread( new objectinputstream(socket.getinputstream()))).start(); } } /** * 用来处理接收过来的鼠标事件或者键盘事件 */ 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(); //得知由客户端传递过来的是一个object对象 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(); } } } /** * 事件处理,用来判断事件类型,并用robot类执行 * @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()); //鼠标拖动 } } } /** * 返回鼠标的真正事件,鼠标时间不能直接处理,需要进过转换 * @return */ public int getmousekey( int button){ if (button == mouseevent.button1){ //鼠标左键 return inputevent.button1_mask; } else if (button == mouseevent.button2){ //鼠标右键 return inputevent.button2_mask; } else if (button == mouseevent.button3){ //滚轮 return inputevent.button3_mask; } else { return 0 ; } } } //屏幕截取器和发送器,这里需要拿到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.*; /** * 用来将图片数据发送 * @author 哑元 * */ public class imagethread implements runnable{ dataoutputstream dos = null ; //数据输出流 public imagethread(dataoutputstream dos){ this .dos = dos; } @override public void run() { try { robot robot = new robot(); //截取整个屏幕 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数组 * @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); //转换成byte数组 return baos.tobytearray(); } } -------------------------------------------------------------------------------------- //client端,用来接收creen图片和发送鼠标事件 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()]; //先拿到传过来的数组长度 dis.readfully(imagebytes); //所有的数据存放到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( "远程控制程序" ); label = new jlabel(); jpanel p = new jpanel(); p.add(label); jscrollpane scroll = new jscrollpane(p); //给p面板添加滚动条 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实现远程桌面的实例代码就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持服务器之家。
原文链接:http://blog.csdn.net/qq_25956141/article/details/78621983