Mercurial > hg > Members > nobuyasu > tightVNCProxy
annotate src/myVncProxy/MyRfbProto.java @ 65:5fca2bb52dc7
create checkMillis
author | e085711 |
---|---|
date | Fri, 22 Jul 2011 03:21:56 +0900 |
parents | 7795e2b5d3ef |
children | 7632606406cb |
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 { | |
445 byte[] b = new byte[4]; | |
446 readFully(b); | |
447 } | |
448 | |
449 void startCheckMills() { | |
450 byte[] b = new byte[4]; | |
451 b = castIntByte(4); | |
452 startCheckTime = System.currentTimeMillis(); | |
453 multicastqueue.put(b); | |
454 } | |
455 | |
456 void endCheckMills() { | |
457 long accTime = System.currentTimeMillis(); | |
458 long time = accTime - startCheckTime; | |
459 System.out.println("checkMillis: " + time); | |
460 } | |
461 | |
462 void printStatus() { | |
463 System.out.println(); | |
464 } | |
465 | |
466 synchronized void changeStatusFlag() { | |
467 printStatusFlag = true; | |
468 } | |
469 | |
470 void printMills() { | |
471 if(printStatusFlag) { | |
472 | |
473 changeStatusFlag(); | |
474 } else { | |
475 changeStatusFlag(); | |
476 } | |
477 } | |
478 | |
43 | 479 |
54 | 480 void newClient(acceptThread acceptThread, final Socket newCli, |
481 final OutputStream os, final InputStream is) throws IOException { | |
482 // createBimgFlag = true; | |
483 // rfb.addSockTmp(newCli); | |
484 // addSock(newCli); | |
485 final Client<byte[]> c = multicastqueue.newClient(); | |
486 Runnable sender = new Runnable() { | |
487 public void run() { | |
488 try { | |
65 | 489 /** |
490 * initial connection of RFB protocol | |
491 */ | |
54 | 492 sendRfbVersion(os); |
493 readVersionMsg(is); | |
494 sendSecurityType(os); | |
495 readSecType(is); | |
496 sendSecResult(os); | |
497 readClientInit(is); | |
498 sendInitData(os); | |
43 | 499 |
54 | 500 for (;;) { |
501 byte[] b = c.poll(); | |
502 os.write(b, 0, b.length); | |
503 } | |
504 } catch (IOException e) { | |
65 | 505 /** |
506 * if socket closed | |
507 */ | |
54 | 508 // cliList.remove(newCli); |
509 } | |
510 | |
511 } | |
512 | |
513 }; | |
514 new Thread(sender).start(); | |
515 | |
516 } | |
517 } |