Mercurial > hg > Members > nobuyasu > tightVNCProxy
comparison src/myVncProxy/MyRfbProto.java @ 54:796f2b3b8665
modify MyRfbProto.java
author | e085711 |
---|---|
date | Fri, 08 Jul 2011 12:38:14 +0900 |
parents | 089bd4510538 |
children | 39741f18b4f2 a240b19b66f0 |
comparison
equal
deleted
inserted
replaced
52:6eb7d0c8f11d | 54:796f2b3b8665 |
---|---|
1 package myVncProxy; | 1 package myVncProxy; |
2 | |
2 import java.awt.Graphics; | 3 import java.awt.Graphics; |
3 import java.awt.Image; | 4 import java.awt.Image; |
4 import java.awt.image.BufferedImage; | 5 import java.awt.image.BufferedImage; |
5 import java.io.BufferedOutputStream; | 6 import java.io.BufferedOutputStream; |
6 import java.io.BufferedReader; | 7 import java.io.BufferedReader; |
14 import java.net.Socket; | 15 import java.net.Socket; |
15 import java.util.LinkedList; | 16 import java.util.LinkedList; |
16 | 17 |
17 import javax.imageio.ImageIO; | 18 import javax.imageio.ImageIO; |
18 | 19 |
20 import myVncProxy.MulticastQueue.Client; | |
21 | |
19 import java.util.concurrent.ExecutorService; | 22 import java.util.concurrent.ExecutorService; |
20 import java.util.concurrent.Executors; | 23 import java.util.concurrent.Executors; |
21 import java.io.OutputStream; | 24 import java.io.OutputStream; |
22 | 25 |
23 class MyRfbProto extends RfbProto { | 26 class MyRfbProto extends RfbProto { |
24 | 27 |
25 final static String versionMsg_3_998 = "RFB 003.998\n"; | 28 final static String versionMsg_3_998 = "RFB 003.998\n"; |
26 | 29 |
27 | |
28 private int messageType; | 30 private int messageType; |
29 private int rectangles; | 31 private int rectangles; |
30 private int rectX; | 32 private int rectX; |
31 private int rectY; | 33 private int rectY; |
32 private int rectW; | 34 private int rectW; |
33 private int rectH; | 35 private int rectH; |
34 private int encoding; | 36 private int encoding; |
35 private int zLen; | 37 private int zLen; |
36 private int dataLen; | 38 private int dataLen; |
37 | 39 |
38 private ServerSocket servSock; | 40 private ServerSocket servSock; |
39 private int acceptPort; | 41 private int acceptPort; |
40 private byte initData[]; | 42 private byte initData[]; |
41 private LinkedList <Socket> cliListTmp; | 43 private LinkedList<Socket> cliListTmp; |
42 private LinkedList <Socket> cliList; | 44 private LinkedList<Socket> cliList; |
43 private LinkedList <Thread> sendThreads; | 45 private LinkedList<Thread> sendThreads; |
44 boolean createBimgFlag; | 46 boolean createBimgFlag; |
45 | 47 |
46 ExecutorService executor; | 48 ExecutorService executor; |
47 | 49 |
48 | |
49 byte[] pngBytes; | 50 byte[] pngBytes; |
50 | 51 |
51 MyRfbProto(String h, int p, VncViewer v ) throws IOException { | 52 private MulticastQueue<byte[]> multicastqueue = new MulticastQueue<byte[]>(); |
53 | |
54 MyRfbProto(String h, int p, VncViewer v) throws IOException { | |
52 super(h, p, v); | 55 super(h, p, v); |
53 cliList = new LinkedList <Socket>(); | 56 cliList = new LinkedList<Socket>(); |
54 cliListTmp = new LinkedList <Socket>(); | 57 cliListTmp = new LinkedList<Socket>(); |
55 createBimgFlag = false; | 58 createBimgFlag = false; |
56 sendThreads = new LinkedList <Thread>(); | 59 sendThreads = new LinkedList<Thread>(); |
57 // executor = Executors.newCachedThreadPool(); | 60 // executor = Executors.newCachedThreadPool(); |
58 executor = Executors.newSingleThreadExecutor(); | 61 // executor = Executors.newSingleThreadExecutor(); |
59 } | 62 } |
60 | 63 |
61 MyRfbProto(String h, int p) throws IOException { | 64 MyRfbProto(String h, int p) throws IOException { |
62 super(h, p); | 65 super(h, p); |
63 cliList = new LinkedList <Socket>(); | 66 cliList = new LinkedList<Socket>(); |
64 cliListTmp = new LinkedList <Socket>(); | 67 cliListTmp = new LinkedList<Socket>(); |
65 createBimgFlag = false; | 68 createBimgFlag = false; |
66 sendThreads = new LinkedList <Thread>(); | 69 sendThreads = new LinkedList<Thread>(); |
67 // executor = Executors.newCachedThreadPool(); | 70 // executor = Executors.newCachedThreadPool(); |
68 executor = Executors.newSingleThreadExecutor(); | 71 // executor = Executors.newSingleThreadExecutor(); |
69 } | 72 } |
70 | 73 |
71 // over write | 74 // over write |
72 void writeVersionMsg() throws IOException { | 75 void writeVersionMsg() throws IOException { |
73 clientMajor = 3; | 76 clientMajor = 3; |
74 if (serverMinor >= 9) { | 77 if (serverMinor >= 9) { |
75 clientMinor = 9; | 78 clientMinor = 9; |
76 os.write(versionMsg_3_998.getBytes()); | 79 os.write(versionMsg_3_998.getBytes()); |
77 } else if (serverMajor > 3 || serverMinor >= 8) { | 80 } else if (serverMajor > 3 || serverMinor >= 8) { |
78 clientMinor = 8; | 81 clientMinor = 8; |
79 os.write(versionMsg_3_8.getBytes()); | 82 os.write(versionMsg_3_8.getBytes()); |
80 } else if (serverMinor >= 9) { | 83 } else if (serverMinor >= 9) { |
81 clientMinor = 9; | 84 clientMinor = 9; |
89 } | 92 } |
90 protocolTightVNC = false; | 93 protocolTightVNC = false; |
91 initCapabilities(); | 94 initCapabilities(); |
92 } | 95 } |
93 | 96 |
94 | 97 void initServSock(int port) throws IOException { |
95 | |
96 void initServSock(int port) throws IOException{ | |
97 servSock = new ServerSocket(port); | 98 servSock = new ServerSocket(port); |
98 acceptPort = port; | 99 acceptPort = port; |
99 } | 100 } |
100 // 5550を開けるが、開いてないなら+1のポートを開ける。 | 101 |
101 void selectPort(){ | 102 // 5550を開けるが、開いてないなら+1のポートを開ける。 |
103 void selectPort() { | |
102 int i = 5550; | 104 int i = 5550; |
103 while(true){ | 105 while (true) { |
104 try{ | 106 try { |
105 initServSock(i); | 107 initServSock(i); |
106 break; | 108 break; |
107 }catch(BindException e){ | 109 } catch (BindException e) { |
108 i++; | 110 i++; |
109 continue; | 111 continue; |
110 }catch(IOException e){ | 112 } catch (IOException e) { |
111 | 113 |
112 } | 114 } |
113 } | 115 } |
114 System.out.println("accept port = "+i); | 116 System.out.println("accept port = " + i); |
115 } | 117 } |
116 int getAcceptPort(){ | 118 |
119 int getAcceptPort() { | |
117 return acceptPort; | 120 return acceptPort; |
118 } | 121 } |
122 | |
119 void setSoTimeout(int num) throws IOException { | 123 void setSoTimeout(int num) throws IOException { |
120 servSock.setSoTimeout(num); | 124 servSock.setSoTimeout(num); |
121 } | 125 } |
122 | 126 |
123 Socket accept() throws IOException { | 127 Socket accept() throws IOException { |
124 return servSock.accept(); | 128 return servSock.accept(); |
125 } | 129 } |
126 | 130 |
127 void addSock(Socket sock){ | 131 void addSock(Socket sock) { |
128 cliList.add(sock); | 132 cliList.add(sock); |
129 } | 133 } |
130 void addSockTmp(Socket sock){ | 134 |
131 System.out.println("connected "+sock.getInetAddress()); | 135 void addSockTmp(Socket sock) { |
136 System.out.println("connected " + sock.getInetAddress()); | |
132 cliListTmp.add(sock); | 137 cliListTmp.add(sock); |
133 } | 138 } |
134 | 139 |
135 void mark(int len) throws IOException { | 140 void mark(int len) throws IOException { |
136 is.mark(len); | 141 is.mark(len); |
137 } | 142 } |
138 | 143 |
139 void reset() throws IOException { | 144 void reset() throws IOException { |
140 is.reset(); | 145 is.reset(); |
141 } | 146 } |
142 | 147 |
143 boolean markSupported() { | 148 boolean markSupported() { |
144 return is.markSupported(); | 149 return is.markSupported(); |
145 } | 150 } |
146 | 151 |
147 void readServerInit() throws IOException { | 152 void readServerInit() throws IOException { |
148 | 153 |
149 mark(255); | 154 mark(255); |
150 skipBytes(20); | 155 skipBytes(20); |
151 int nlen = readU32(); | 156 int nlen = readU32(); |
152 int blen = 20+4+nlen; | 157 int blen = 20 + 4 + nlen; |
153 initData = new byte[blen]; | 158 initData = new byte[blen]; |
154 reset(); | 159 reset(); |
155 | 160 |
156 mark(blen); | 161 mark(blen); |
157 readFully(initData); | 162 readFully(initData); |
158 reset(); | 163 reset(); |
159 | 164 |
160 framebufferWidth = readU16(); | 165 framebufferWidth = readU16(); |
161 framebufferHeight = readU16(); | 166 framebufferHeight = readU16(); |
162 bitsPerPixel = readU8(); | 167 bitsPerPixel = readU8(); |
163 depth = readU8(); | 168 depth = readU8(); |
164 bigEndian = (readU8() != 0); | 169 bigEndian = (readU8() != 0); |
188 } | 193 } |
189 | 194 |
190 inNormalProtocol = true; | 195 inNormalProtocol = true; |
191 } | 196 } |
192 | 197 |
193 void sendRfbVersion(OutputStream os) throws IOException{ | 198 void sendRfbVersion(OutputStream os) throws IOException { |
194 os.write(versionMsg_3_998.getBytes()); | 199 os.write(versionMsg_3_998.getBytes()); |
195 } | 200 } |
201 | |
196 void readVersionMsg(InputStream is) throws IOException { | 202 void readVersionMsg(InputStream is) throws IOException { |
197 | 203 |
198 byte[] b = new byte[12]; | 204 byte[] b = new byte[12]; |
199 | 205 |
200 is.read(b); | 206 is.read(b); |
212 serverMinor = (b[8] - '0') * 100 + (b[9] - '0') * 10 + (b[10] - '0'); | 218 serverMinor = (b[8] - '0') * 100 + (b[9] - '0') * 10 + (b[10] - '0'); |
213 | 219 |
214 if (serverMajor < 3) { | 220 if (serverMajor < 3) { |
215 throw new IOException( | 221 throw new IOException( |
216 "RFB server does not support protocol version 3"); | 222 "RFB server does not support protocol version 3"); |
217 } | 223 } |
218 | 224 |
219 } | 225 } |
226 | |
220 void sendSecurityType(OutputStream os) throws IOException { | 227 void sendSecurityType(OutputStream os) throws IOException { |
221 // number-of-security-types | 228 // number-of-security-types |
222 os.write(1); | 229 os.write(1); |
223 // security-types | 230 // security-types |
224 // 1:None | 231 // 1:None |
225 os.write(1); | 232 os.write(1); |
226 } | 233 } |
234 | |
227 void readSecType(InputStream is) throws IOException { | 235 void readSecType(InputStream is) throws IOException { |
228 byte[] b = new byte[1]; | 236 byte[] b = new byte[1]; |
229 is.read(b); | 237 is.read(b); |
230 | 238 |
231 } | 239 } |
240 | |
232 void sendSecResult(OutputStream os) throws IOException { | 241 void sendSecResult(OutputStream os) throws IOException { |
233 byte[] b = castIntByte(0); | 242 byte[] b = castIntByte(0); |
234 os.write(b); | 243 os.write(b); |
235 } | 244 } |
236 | 245 |
237 void readClientInit(InputStream in) throws IOException { | 246 void readClientInit(InputStream in) throws IOException { |
238 byte[] b = new byte[0]; | 247 byte[] b = new byte[0]; |
239 in.read(b); | 248 in.read(b); |
240 } | 249 } |
241 | 250 |
242 void sendInitData(OutputStream os) throws IOException{ | 251 void sendInitData(OutputStream os) throws IOException { |
243 os.write(initData); | 252 os.write(initData); |
244 } | 253 } |
245 | 254 |
246 void sendData(byte b[]){ | 255 void sendData(byte b[]) { |
247 try{ | 256 try { |
248 for(Socket cli : cliList){ | 257 multicastqueue.put(b); |
249 try{ | 258 |
250 cli.getOutputStream().write(b, 0, b.length); | 259 /* |
251 }catch(IOException e){ | 260 * // for(Socket cli : cliList){ // try{ // |
252 // if socket closed | 261 * cli.getOutputStream().write(b, 0, b.length); // |
253 cliList.remove(cli); | 262 * }catch(IOException e){ // // if socket closed // |
254 } | 263 * cliList.remove(cli); // } // } |
255 } | 264 */ |
256 // System.out.println("cliSize="+cliSize()); | 265 // System.out.println("cliSize="+cliSize()); |
257 }catch(Exception e){ | 266 } catch (Exception e) { |
258 } | 267 } |
259 } | 268 } |
260 | 269 |
261 void sendPngImage(){ | 270 void sendPngImage() { |
262 try{ | 271 try { |
263 for(Socket cli : cliListTmp){ | 272 for (Socket cli : cliListTmp) { |
264 try{ | 273 try { |
265 sendPngData(cli); | 274 sendPngData(cli); |
266 addSock(cli); | 275 addSock(cli); |
267 }catch(IOException e){ | 276 } catch (IOException e) { |
268 // if socket closed | 277 // if socket closed |
269 cliListTmp.remove(cli); | 278 cliListTmp.remove(cli); |
270 } | 279 } |
271 } | 280 } |
272 // System.out.println("cliSize="+cliSize()); | 281 // System.out.println("cliSize="+cliSize()); |
273 }catch(Exception e){ | 282 } catch (Exception e) { |
274 } | 283 } |
275 cliListTmp.clear(); | 284 cliListTmp.clear(); |
276 } | 285 } |
277 | |
278 | |
279 | 286 |
280 boolean ready() throws IOException { | 287 boolean ready() throws IOException { |
281 BufferedReader br = new BufferedReader(new InputStreamReader(is)); | 288 BufferedReader br = new BufferedReader(new InputStreamReader(is)); |
282 return br.ready(); | 289 return br.ready(); |
283 } | 290 } |
284 | 291 |
285 int cliSize(){ | 292 int cliSize() { |
286 return cliList.size(); | 293 return cliList.size(); |
287 } | 294 } |
288 void printNumBytesRead(){ | 295 |
289 System.out.println("numBytesRead="+numBytesRead); | 296 void printNumBytesRead() { |
290 } | 297 System.out.println("numBytesRead=" + numBytesRead); |
298 } | |
299 | |
291 void bufResetSend(int size) throws IOException { | 300 void bufResetSend(int size) throws IOException { |
292 reset(); | 301 reset(); |
293 int len = size; | 302 int len = size; |
294 if(available() < size ) | 303 if (available() < size) |
295 len = available(); | 304 len = available(); |
296 byte buffer[] = new byte[len]; | 305 byte buffer[] = new byte[len]; |
297 readFully(buffer); | 306 readFully(buffer); |
298 sendData(buffer); | 307 sendData(buffer); |
299 } | 308 } |
300 void readSendData()throws IOException{ | 309 |
310 void readSendData() throws IOException { | |
301 byte buffer[] = new byte[dataLen]; | 311 byte buffer[] = new byte[dataLen]; |
302 readFully(buffer); | 312 readFully(buffer); |
303 reset(); | 313 reset(); |
304 | 314 |
305 for(Socket cli : cliList){ | 315 for (Socket cli : cliList) { |
306 try{ | 316 try { |
307 OutputStream out = cli.getOutputStream(); | 317 OutputStream out = cli.getOutputStream(); |
308 executor.execute(new SendThread(out, buffer)); | 318 executor.execute(new SendThread(out, buffer)); |
309 }catch(IOException e){ | 319 } catch (IOException e) { |
310 // if client socket closed | 320 // if client socket closed |
311 cliListTmp.remove(cli); | 321 cliListTmp.remove(cli); |
312 }catch(Exception e){ | 322 } catch (Exception e) { |
313 | 323 |
314 } | 324 } |
315 | 325 |
316 } | 326 } |
317 } | 327 } |
318 void regiFramebufferUpdate()throws IOException{ | 328 |
329 void regiFramebufferUpdate() throws IOException { | |
319 mark(20); | 330 mark(20); |
320 messageType = readU8(); | 331 messageType = readU8(); |
321 skipBytes(1); | 332 skipBytes(1); |
322 rectangles = readU16(); | 333 rectangles = readU16(); |
323 rectX = readU16(); | 334 rectX = readU16(); |
324 rectY = readU16(); | 335 rectY = readU16(); |
325 rectW = readU16(); | 336 rectW = readU16(); |
326 rectH = readU16(); | 337 rectH = readU16(); |
327 encoding = readU32(); | 338 encoding = readU32(); |
328 if(encoding == 16) | 339 if (encoding == 16) |
329 zLen = readU32(); | 340 zLen = readU32(); |
330 reset(); | 341 reset(); |
331 } | 342 } |
332 void checkAndMark() throws IOException{ | 343 |
333 switch(encoding){ | 344 void checkAndMark() throws IOException { |
345 switch (encoding) { | |
334 case RfbProto.EncodingRaw: | 346 case RfbProto.EncodingRaw: |
335 dataLen = rectW * rectH * 4 + 16; | 347 dataLen = rectW * rectH * 4 + 16; |
336 mark(dataLen); | 348 mark(dataLen); |
337 break; | 349 break; |
338 case RfbProto.EncodingZRLE: | 350 case RfbProto.EncodingZRLE: |
339 dataLen = zLen+20; | 351 dataLen = zLen + 20; |
340 mark(dataLen); | 352 mark(dataLen); |
341 break; | 353 break; |
342 default: | 354 default: |
343 mark(1000000); | 355 mark(1000000); |
344 } | 356 } |
345 } | 357 } |
346 BufferedImage createBufferedImage(Image img){ | 358 |
347 BufferedImage bimg = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB ); | 359 BufferedImage createBufferedImage(Image img) { |
360 BufferedImage bimg = new BufferedImage(img.getWidth(null), | |
361 img.getHeight(null), BufferedImage.TYPE_INT_RGB); | |
348 | 362 |
349 Graphics g = bimg.getGraphics(); | 363 Graphics g = bimg.getGraphics(); |
350 g.drawImage(img, 0, 0, null); | 364 g.drawImage(img, 0, 0, null); |
351 g.dispose(); | 365 g.dispose(); |
352 return bimg; | 366 return bimg; |
353 } | 367 } |
354 | 368 |
355 void createPngBytes(BufferedImage bimg)throws IOException { | 369 void createPngBytes(BufferedImage bimg) throws IOException { |
356 pngBytes = getImageBytes(bimg , "png"); | 370 pngBytes = getImageBytes(bimg, "png"); |
357 } | 371 } |
358 byte[] getBytes(BufferedImage img)throws IOException { | 372 |
373 byte[] getBytes(BufferedImage img) throws IOException { | |
359 byte[] b = getImageBytes(img, "png"); | 374 byte[] b = getImageBytes(img, "png"); |
360 return b; | 375 return b; |
361 } | 376 } |
362 | 377 |
363 byte[] getImageBytes(BufferedImage image, String imageFormat) throws IOException { | 378 byte[] getImageBytes(BufferedImage image, String imageFormat) |
379 throws IOException { | |
364 ByteArrayOutputStream bos = new ByteArrayOutputStream(); | 380 ByteArrayOutputStream bos = new ByteArrayOutputStream(); |
365 BufferedOutputStream os = new BufferedOutputStream(bos); | 381 BufferedOutputStream os = new BufferedOutputStream(bos); |
366 image.flush(); | 382 image.flush(); |
367 ImageIO.write(image, imageFormat, os); | 383 ImageIO.write(image, imageFormat, os); |
368 os.flush(); | 384 os.flush(); |
369 os.close(); | 385 os.close(); |
370 return bos.toByteArray(); | 386 return bos.toByteArray(); |
371 } | 387 } |
372 | 388 |
373 void sendPngData(Socket sock)throws IOException{ | 389 void sendPngData(Socket sock) throws IOException { |
374 byte[] dataLength = castIntByte(pngBytes.length); | 390 byte[] dataLength = castIntByte(pngBytes.length); |
375 sock.getOutputStream().write(dataLength); | 391 sock.getOutputStream().write(dataLength); |
376 sock.getOutputStream().write(pngBytes); | 392 sock.getOutputStream().write(pngBytes); |
377 } | 393 } |
378 byte[] castIntByte(int len){ | 394 |
395 byte[] castIntByte(int len) { | |
379 byte[] b = new byte[4]; | 396 byte[] b = new byte[4]; |
380 b[0] = (byte)((len >>> 24 ) & 0xFF); | 397 b[0] = (byte) ((len >>> 24) & 0xFF); |
381 b[1] = (byte)((len >>> 16 ) & 0xFF); | 398 b[1] = (byte) ((len >>> 16) & 0xFF); |
382 b[2] = (byte)((len >>> 8 ) & 0xFF); | 399 b[2] = (byte) ((len >>> 8) & 0xFF); |
383 b[3] = (byte)((len >>> 0 ) & 0xFF); | 400 b[3] = (byte) ((len >>> 0) & 0xFF); |
384 return b; | 401 return b; |
385 } | 402 } |
386 | 403 |
387 BufferedImage createBimg()throws IOException{ | 404 BufferedImage createBimg() throws IOException { |
388 BufferedImage bimg = ImageIO.read(new ByteArrayInputStream(pngBytes)); | 405 BufferedImage bimg = ImageIO.read(new ByteArrayInputStream(pngBytes)); |
389 return bimg; | 406 return bimg; |
390 } | 407 } |
391 void readPngData()throws IOException{ | 408 |
409 void readPngData() throws IOException { | |
392 pngBytes = new byte[is.available()]; | 410 pngBytes = new byte[is.available()]; |
393 readFully(pngBytes); | 411 readFully(pngBytes); |
394 } | 412 } |
395 void printFramebufferUpdate(){ | 413 |
396 | 414 void printFramebufferUpdate() { |
415 | |
397 System.out.println("messageType=" + messageType); | 416 System.out.println("messageType=" + messageType); |
398 System.out.println("rectangles="+rectangles); | 417 System.out.println("rectangles=" + rectangles); |
399 System.out.println("encoding=" + encoding); | 418 System.out.println("encoding=" + encoding); |
400 switch(encoding){ | 419 switch (encoding) { |
401 case RfbProto.EncodingRaw: | 420 case RfbProto.EncodingRaw: |
402 System.out.println("rectW * rectH * 4 + 16 =" + rectW * rectH * 4 + 16); | 421 System.out.println("rectW * rectH * 4 + 16 =" + rectW * rectH * 4 |
422 + 16); | |
403 break; | 423 break; |
404 default: | 424 default: |
405 } | 425 } |
406 } | 426 } |
427 | |
428 void newClient(acceptThread acceptThread, final Socket newCli, | |
429 final OutputStream os, final InputStream is) throws IOException { | |
430 // createBimgFlag = true; | |
431 // rfb.addSockTmp(newCli); | |
432 // addSock(newCli); | |
433 final Client<byte[]> c = multicastqueue.newClient(); | |
434 Runnable sender = new Runnable() { | |
435 @Override | |
436 public void run() { | |
437 try { | |
438 // 初期接続確立の部分 | |
439 sendRfbVersion(os); | |
440 readVersionMsg(is); | |
441 sendSecurityType(os); | |
442 readSecType(is); | |
443 sendSecResult(os); | |
444 readClientInit(is); | |
445 sendInitData(os); | |
446 | |
447 for (;;) { | |
448 byte[] b = c.poll(); | |
449 os.write(b, 0, b.length); | |
450 } | |
451 } catch (IOException e) { | |
452 //接続が切れた処理 | |
453 //lockしないと駄目 | |
454 // cliList.remove(newCli); | |
455 } | |
456 | |
457 } | |
458 | |
459 }; | |
460 new Thread(sender).start(); | |
461 | |
462 } | |
407 } | 463 } |
408 | |
409 |