Mercurial > hg > Members > nobuyasu > tightVNCProxy
annotate src/myVncProxy/MyRfbProto.java @ 66:7632606406cb
create sendCheckMillis
author | e085711 |
---|---|
date | Tue, 26 Jul 2011 13:03:08 +0900 |
parents | 5fca2bb52dc7 |
children | f695bc56eb4f |
rev | line source |
---|---|
24 | 1 package myVncProxy; |
54 | 2 |
25 | 3 import java.awt.Graphics; |
4 import java.awt.Image; | |
5 import java.awt.image.BufferedImage; | |
6 import java.io.BufferedOutputStream; | |
15 | 7 import java.io.BufferedReader; |
25 | 8 import java.io.ByteArrayInputStream; |
9 import java.io.ByteArrayOutputStream; | |
10 | 10 import java.io.IOException; |
43 | 11 import java.io.InputStream; |
15 | 12 import java.io.InputStreamReader; |
23 | 13 import java.net.BindException; |
10 | 14 import java.net.ServerSocket; |
15 import java.net.Socket; | |
16 import java.util.LinkedList; | |
17 | |
25 | 18 import javax.imageio.ImageIO; |
19 | |
54 | 20 import myVncProxy.MulticastQueue.Client; |
21 | |
40 | 22 import java.util.concurrent.ExecutorService; |
23 import java.util.concurrent.Executors; | |
24 import java.io.OutputStream; | |
10 | 25 |
26 class MyRfbProto extends RfbProto { | |
43 | 27 final static String versionMsg_3_998 = "RFB 003.998\n"; |
65 | 28 /** |
29 * CheckMillis is one of new msgType for RFB 3.998. | |
30 */ | |
31 final static int CheckMillis = 4; | |
32 boolean printStatusFlag = false; | |
33 long startCheckTime; | |
54 | 34 |
18 | 35 private int messageType; |
36 private int rectangles; | |
23 | 37 private int rectX; |
38 private int rectY; | |
39 private int rectW; | |
40 private int rectH; | |
18 | 41 private int encoding; |
27 | 42 private int zLen; |
18 | 43 |
23 | 44 private ServerSocket servSock; |
45 private int acceptPort; | |
10 | 46 private byte initData[]; |
54 | 47 private LinkedList<Socket> cliListTmp; |
48 private LinkedList<Socket> cliList; | |
49 private LinkedList<Thread> sendThreads; | |
27 | 50 boolean createBimgFlag; |
54 | 51 |
40 | 52 ExecutorService executor; |
54 | 53 |
25 | 54 byte[] pngBytes; |
54 | 55 |
56 private MulticastQueue<byte[]> multicastqueue = new MulticastQueue<byte[]>(); | |
57 | |
58 MyRfbProto(String h, int p, VncViewer v) throws IOException { | |
10 | 59 super(h, p, v); |
54 | 60 cliList = new LinkedList<Socket>(); |
61 cliListTmp = new LinkedList<Socket>(); | |
27 | 62 createBimgFlag = false; |
61 | 63 // sendThreads = new LinkedList<Thread>(); |
54 | 64 // executor = Executors.newCachedThreadPool(); |
65 // executor = Executors.newSingleThreadExecutor(); | |
10 | 66 } |
67 | |
13 | 68 MyRfbProto(String h, int p) throws IOException { |
69 super(h, p); | |
54 | 70 cliList = new LinkedList<Socket>(); |
71 cliListTmp = new LinkedList<Socket>(); | |
27 | 72 createBimgFlag = false; |
61 | 73 // sendThreads = new LinkedList<Thread>(); |
54 | 74 // executor = Executors.newCachedThreadPool(); |
75 // executor = Executors.newSingleThreadExecutor(); | |
13 | 76 } |
24 | 77 |
44 | 78 // over write |
43 | 79 void writeVersionMsg() throws IOException { |
80 clientMajor = 3; | |
81 if (serverMinor >= 9) { | |
54 | 82 clientMinor = 9; |
83 os.write(versionMsg_3_998.getBytes()); | |
43 | 84 } else if (serverMajor > 3 || serverMinor >= 8) { |
85 clientMinor = 8; | |
86 os.write(versionMsg_3_8.getBytes()); | |
87 } else if (serverMinor >= 9) { | |
88 clientMinor = 9; | |
89 os.write(versionMsg_3_998.getBytes()); | |
90 } else if (serverMinor >= 7) { | |
91 clientMinor = 7; | |
92 os.write(versionMsg_3_7.getBytes()); | |
93 } else { | |
94 clientMinor = 3; | |
95 os.write(versionMsg_3_3.getBytes()); | |
96 } | |
97 protocolTightVNC = false; | |
98 initCapabilities(); | |
99 } | |
100 | |
54 | 101 void initServSock(int port) throws IOException { |
10 | 102 servSock = new ServerSocket(port); |
23 | 103 acceptPort = port; |
10 | 104 } |
54 | 105 |
106 // 5550を開けるが、開いてないなら+1のポートを開ける。 | |
107 void selectPort() { | |
23 | 108 int i = 5550; |
54 | 109 while (true) { |
110 try { | |
23 | 111 initServSock(i); |
112 break; | |
54 | 113 } catch (BindException e) { |
23 | 114 i++; |
115 continue; | |
54 | 116 } catch (IOException e) { |
10 | 117 |
23 | 118 } |
119 } | |
54 | 120 System.out.println("accept port = " + i); |
23 | 121 } |
54 | 122 |
123 int getAcceptPort() { | |
23 | 124 return acceptPort; |
125 } | |
54 | 126 |
10 | 127 void setSoTimeout(int num) throws IOException { |
128 servSock.setSoTimeout(num); | |
129 } | |
54 | 130 |
10 | 131 Socket accept() throws IOException { |
132 return servSock.accept(); | |
133 } | |
134 | |
54 | 135 void addSock(Socket sock) { |
10 | 136 cliList.add(sock); |
137 } | |
54 | 138 |
139 void addSockTmp(Socket sock) { | |
140 System.out.println("connected " + sock.getInetAddress()); | |
27 | 141 cliListTmp.add(sock); |
142 } | |
54 | 143 |
10 | 144 void mark(int len) throws IOException { |
145 is.mark(len); | |
146 } | |
147 | |
148 void reset() throws IOException { | |
149 is.reset(); | |
54 | 150 } |
10 | 151 |
152 boolean markSupported() { | |
153 return is.markSupported(); | |
154 } | |
54 | 155 |
10 | 156 void readServerInit() throws IOException { |
54 | 157 |
10 | 158 mark(255); |
159 skipBytes(20); | |
160 int nlen = readU32(); | |
54 | 161 int blen = 20 + 4 + nlen; |
10 | 162 initData = new byte[blen]; |
163 reset(); | |
164 | |
165 mark(blen); | |
166 readFully(initData); | |
167 reset(); | |
54 | 168 |
10 | 169 framebufferWidth = readU16(); |
170 framebufferHeight = readU16(); | |
171 bitsPerPixel = readU8(); | |
172 depth = readU8(); | |
173 bigEndian = (readU8() != 0); | |
174 trueColour = (readU8() != 0); | |
175 redMax = readU16(); | |
176 greenMax = readU16(); | |
177 blueMax = readU16(); | |
178 redShift = readU8(); | |
179 greenShift = readU8(); | |
180 blueShift = readU8(); | |
181 byte[] pad = new byte[3]; | |
182 readFully(pad); | |
183 int nameLength = readU32(); | |
184 byte[] name = new byte[nameLength]; | |
185 readFully(name); | |
186 desktopName = new String(name); | |
187 | |
188 // Read interaction capabilities (TightVNC protocol extensions) | |
189 if (protocolTightVNC) { | |
190 int nServerMessageTypes = readU16(); | |
191 int nClientMessageTypes = readU16(); | |
192 int nEncodingTypes = readU16(); | |
193 readU16(); | |
194 readCapabilityList(serverMsgCaps, nServerMessageTypes); | |
195 readCapabilityList(clientMsgCaps, nClientMessageTypes); | |
196 readCapabilityList(encodingCaps, nEncodingTypes); | |
197 } | |
198 | |
199 inNormalProtocol = true; | |
200 } | |
201 | |
54 | 202 void sendRfbVersion(OutputStream os) throws IOException { |
203 os.write(versionMsg_3_998.getBytes()); | |
43 | 204 } |
54 | 205 |
45 | 206 void readVersionMsg(InputStream is) throws IOException { |
207 | |
208 byte[] b = new byte[12]; | |
209 | |
210 is.read(b); | |
211 | |
212 if ((b[0] != 'R') || (b[1] != 'F') || (b[2] != 'B') || (b[3] != ' ') | |
213 || (b[4] < '0') || (b[4] > '9') || (b[5] < '0') || (b[5] > '9') | |
214 || (b[6] < '0') || (b[6] > '9') || (b[7] != '.') | |
215 || (b[8] < '0') || (b[8] > '9') || (b[9] < '0') || (b[9] > '9') | |
216 || (b[10] < '0') || (b[10] > '9') || (b[11] != '\n')) { | |
217 throw new IOException("Host " + host + " port " + port | |
218 + " is not an RFB server"); | |
219 } | |
220 | |
221 serverMajor = (b[4] - '0') * 100 + (b[5] - '0') * 10 + (b[6] - '0'); | |
222 serverMinor = (b[8] - '0') * 100 + (b[9] - '0') * 10 + (b[10] - '0'); | |
223 | |
224 if (serverMajor < 3) { | |
225 throw new IOException( | |
226 "RFB server does not support protocol version 3"); | |
54 | 227 } |
228 | |
229 } | |
230 | |
43 | 231 void sendSecurityType(OutputStream os) throws IOException { |
232 // number-of-security-types | |
233 os.write(1); | |
54 | 234 // security-types |
43 | 235 // 1:None |
236 os.write(1); | |
237 } | |
54 | 238 |
46
11da7dacbc1a
modify MyRfbProto.java and acceptThread.java add readSecType
e085711
parents:
45
diff
changeset
|
239 void readSecType(InputStream is) throws IOException { |
11da7dacbc1a
modify MyRfbProto.java and acceptThread.java add readSecType
e085711
parents:
45
diff
changeset
|
240 byte[] b = new byte[1]; |
11da7dacbc1a
modify MyRfbProto.java and acceptThread.java add readSecType
e085711
parents:
45
diff
changeset
|
241 is.read(b); |
11da7dacbc1a
modify MyRfbProto.java and acceptThread.java add readSecType
e085711
parents:
45
diff
changeset
|
242 |
11da7dacbc1a
modify MyRfbProto.java and acceptThread.java add readSecType
e085711
parents:
45
diff
changeset
|
243 } |
54 | 244 |
47
b2bf4e44504a
modify MyRfbProto.java and acceptThread.java , add sendSecResult
e085711
parents:
46
diff
changeset
|
245 void sendSecResult(OutputStream os) throws IOException { |
b2bf4e44504a
modify MyRfbProto.java and acceptThread.java , add sendSecResult
e085711
parents:
46
diff
changeset
|
246 byte[] b = castIntByte(0); |
b2bf4e44504a
modify MyRfbProto.java and acceptThread.java , add sendSecResult
e085711
parents:
46
diff
changeset
|
247 os.write(b); |
b2bf4e44504a
modify MyRfbProto.java and acceptThread.java , add sendSecResult
e085711
parents:
46
diff
changeset
|
248 } |
54 | 249 |
43 | 250 void readClientInit(InputStream in) throws IOException { |
251 byte[] b = new byte[0]; | |
252 in.read(b); | |
253 } | |
54 | 254 |
255 void sendInitData(OutputStream os) throws IOException { | |
256 os.write(initData); | |
10 | 257 } |
258 | |
54 | 259 void sendData(byte b[]) { |
260 try { | |
261 multicastqueue.put(b); | |
262 | |
263 /* | |
264 * // for(Socket cli : cliList){ // try{ // | |
265 * cli.getOutputStream().write(b, 0, b.length); // | |
266 * }catch(IOException e){ // // if socket closed // | |
267 * cliList.remove(cli); // } // } | |
268 */ | |
269 // System.out.println("cliSize="+cliSize()); | |
270 } catch (Exception e) { | |
17 | 271 } |
27 | 272 } |
54 | 273 |
274 void sendPngImage() { | |
275 try { | |
276 for (Socket cli : cliListTmp) { | |
277 try { | |
27 | 278 sendPngData(cli); |
279 addSock(cli); | |
54 | 280 } catch (IOException e) { |
27 | 281 // if socket closed |
282 cliListTmp.remove(cli); | |
283 } | |
284 } | |
54 | 285 // System.out.println("cliSize="+cliSize()); |
286 } catch (Exception e) { | |
27 | 287 } |
288 cliListTmp.clear(); | |
289 } | |
290 | |
15 | 291 boolean ready() throws IOException { |
292 BufferedReader br = new BufferedReader(new InputStreamReader(is)); | |
293 return br.ready(); | |
54 | 294 } |
10 | 295 |
54 | 296 int cliSize() { |
10 | 297 return cliList.size(); |
54 | 298 } |
299 | |
300 void printNumBytesRead() { | |
301 System.out.println("numBytesRead=" + numBytesRead); | |
302 } | |
303 | |
15 | 304 void bufResetSend(int size) throws IOException { |
305 reset(); | |
306 int len = size; | |
54 | 307 if (available() < size) |
15 | 308 len = available(); |
309 byte buffer[] = new byte[len]; | |
310 readFully(buffer); | |
311 sendData(buffer); | |
312 } | |
54 | 313 |
61 | 314 |
54 | 315 void regiFramebufferUpdate() throws IOException { |
27 | 316 mark(20); |
18 | 317 messageType = readU8(); |
318 skipBytes(1); | |
319 rectangles = readU16(); | |
23 | 320 rectX = readU16(); |
321 rectY = readU16(); | |
322 rectW = readU16(); | |
323 rectH = readU16(); | |
27 | 324 encoding = readU32(); |
54 | 325 if (encoding == 16) |
27 | 326 zLen = readU32(); |
23 | 327 reset(); |
15 | 328 } |
54 | 329 |
61 | 330 int checkAndMark() throws IOException { |
331 int dataLen; | |
54 | 332 switch (encoding) { |
23 | 333 case RfbProto.EncodingRaw: |
39 | 334 dataLen = rectW * rectH * 4 + 16; |
335 mark(dataLen); | |
23 | 336 break; |
27 | 337 case RfbProto.EncodingZRLE: |
54 | 338 dataLen = zLen + 20; |
39 | 339 mark(dataLen); |
27 | 340 break; |
23 | 341 default: |
61 | 342 dataLen = 1000000; |
62 | 343 mark(dataLen); |
54 | 344 } |
61 | 345 return dataLen; |
346 } | |
65 | 347 |
61 | 348 void readSendData(int dataLen) throws IOException { |
349 byte buffer[] = new byte[dataLen]; | |
350 readFully(buffer); | |
351 multicastqueue.put(buffer); | |
352 reset(); | |
65 | 353 |
61 | 354 /* |
355 for (Socket cli : cliList) { | |
356 try { | |
357 OutputStream out = cli.getOutputStream(); | |
358 executor.execute(new SendThread(out, buffer)); | |
359 } catch (IOException e) { | |
360 // if client socket closed | |
361 cliListTmp.remove(cli); | |
362 } catch (Exception e) { | |
363 | |
364 } | |
365 | |
366 } | |
367 */ | |
368 } | |
369 void sendDataToClient() throws IOException { | |
370 regiFramebufferUpdate(); | |
371 int dataLen = checkAndMark(); | |
372 readSendData(dataLen); | |
23 | 373 } |
54 | 374 |
375 BufferedImage createBufferedImage(Image img) { | |
376 BufferedImage bimg = new BufferedImage(img.getWidth(null), | |
377 img.getHeight(null), BufferedImage.TYPE_INT_RGB); | |
27 | 378 |
25 | 379 Graphics g = bimg.getGraphics(); |
380 g.drawImage(img, 0, 0, null); | |
381 g.dispose(); | |
382 return bimg; | |
383 } | |
384 | |
54 | 385 void createPngBytes(BufferedImage bimg) throws IOException { |
386 pngBytes = getImageBytes(bimg, "png"); | |
25 | 387 } |
54 | 388 |
389 byte[] getBytes(BufferedImage img) throws IOException { | |
25 | 390 byte[] b = getImageBytes(img, "png"); |
391 return b; | |
392 } | |
54 | 393 |
394 byte[] getImageBytes(BufferedImage image, String imageFormat) | |
395 throws IOException { | |
25 | 396 ByteArrayOutputStream bos = new ByteArrayOutputStream(); |
397 BufferedOutputStream os = new BufferedOutputStream(bos); | |
398 image.flush(); | |
399 ImageIO.write(image, imageFormat, os); | |
400 os.flush(); | |
401 os.close(); | |
402 return bos.toByteArray(); | |
403 } | |
404 | |
54 | 405 void sendPngData(Socket sock) throws IOException { |
26 | 406 byte[] dataLength = castIntByte(pngBytes.length); |
407 sock.getOutputStream().write(dataLength); | |
25 | 408 sock.getOutputStream().write(pngBytes); |
409 } | |
54 | 410 |
411 byte[] castIntByte(int len) { | |
26 | 412 byte[] b = new byte[4]; |
54 | 413 b[0] = (byte) ((len >>> 24) & 0xFF); |
414 b[1] = (byte) ((len >>> 16) & 0xFF); | |
415 b[2] = (byte) ((len >>> 8) & 0xFF); | |
416 b[3] = (byte) ((len >>> 0) & 0xFF); | |
26 | 417 return b; |
418 } | |
54 | 419 |
420 BufferedImage createBimg() throws IOException { | |
25 | 421 BufferedImage bimg = ImageIO.read(new ByteArrayInputStream(pngBytes)); |
422 return bimg; | |
423 } | |
65 | 424 /* |
54 | 425 void readPngData() throws IOException { |
25 | 426 pngBytes = new byte[is.available()]; |
427 readFully(pngBytes); | |
428 } | |
65 | 429 */ |
54 | 430 void printFramebufferUpdate() { |
431 | |
18 | 432 System.out.println("messageType=" + messageType); |
54 | 433 System.out.println("rectangles=" + rectangles); |
18 | 434 System.out.println("encoding=" + encoding); |
54 | 435 switch (encoding) { |
23 | 436 case RfbProto.EncodingRaw: |
54 | 437 System.out.println("rectW * rectH * 4 + 16 =" + rectW * rectH * 4 |
438 + 16); | |
23 | 439 break; |
440 default: | |
441 } | |
18 | 442 } |
65 | 443 |
444 void readCheckMillis() throws IOException { | |
66 | 445 byte[] b = new byte[2]; |
65 | 446 readFully(b); |
447 } | |
448 | |
66 | 449 void startCheckMillis() { |
450 byte[] b = new byte[2]; | |
451 b[0] = (byte) CheckMillis; | |
452 b[1] = (byte) 0; | |
453 startCheckTime = System.currentTimeMillis(); | |
454 System.out.println("startChckTime = "+ startCheckTime); | |
65 | 455 multicastqueue.put(b); |
456 } | |
457 | |
458 void endCheckMills() { | |
459 long accTime = System.currentTimeMillis(); | |
460 long time = accTime - startCheckTime; | |
461 System.out.println("checkMillis: " + time); | |
462 } | |
463 | |
464 void printStatus() { | |
465 System.out.println(); | |
466 } | |
467 | |
468 synchronized void changeStatusFlag() { | |
469 printStatusFlag = true; | |
470 } | |
471 | |
472 void printMills() { | |
473 if(printStatusFlag) { | |
474 | |
475 changeStatusFlag(); | |
476 } else { | |
477 changeStatusFlag(); | |
478 } | |
479 } | |
480 | |
43 | 481 |
54 | 482 void newClient(acceptThread acceptThread, final Socket newCli, |
483 final OutputStream os, final InputStream is) throws IOException { | |
484 // createBimgFlag = true; | |
485 // rfb.addSockTmp(newCli); | |
486 // addSock(newCli); | |
487 final Client<byte[]> c = multicastqueue.newClient(); | |
488 Runnable sender = new Runnable() { | |
489 public void run() { | |
490 try { | |
65 | 491 /** |
492 * initial connection of RFB protocol | |
493 */ | |
54 | 494 sendRfbVersion(os); |
495 readVersionMsg(is); | |
496 sendSecurityType(os); | |
497 readSecType(is); | |
498 sendSecResult(os); | |
499 readClientInit(is); | |
500 sendInitData(os); | |
43 | 501 |
54 | 502 for (;;) { |
503 byte[] b = c.poll(); | |
504 os.write(b, 0, b.length); | |
505 } | |
506 } catch (IOException e) { | |
65 | 507 /** |
508 * if socket closed | |
509 */ | |
54 | 510 // cliList.remove(newCli); |
511 } | |
512 | |
513 } | |
514 | |
515 }; | |
516 new Thread(sender).start(); | |
517 | |
518 } | |
66 | 519 |
520 void sendCheckMillis() { | |
521 | |
522 Runnable stdin = new Runnable() { | |
523 public void run() { | |
524 int c; | |
525 try { | |
526 while( (c = System.in.read()) != -1 ) { | |
527 switch(c) { | |
528 case 's': | |
529 break; | |
530 default: | |
531 startCheckMillis(); | |
532 break; | |
533 } | |
534 } | |
535 }catch(IOException e){ | |
536 System.out.println(e); | |
537 } | |
538 } | |
539 }; | |
540 | |
541 new Thread(stdin).start(); | |
542 } | |
543 | |
54 | 544 } |
66 | 545 |
546 |