Mercurial > hg > Applications > TightVNC_orginal
annotate src/main/java/jp/ac/u_ryukyu/treevnc/server/MyRfbProtoProxy.java @ 23:6a4312344a5a
remove set rfb TreeTask
author | one |
---|---|
date | Thu, 30 Aug 2012 14:40:32 +0900 |
parents | bfddb801c3aa |
children | 73b13bc335c2 |
rev | line source |
---|---|
12 | 1 package jp.ac.u_ryukyu.treevnc.server; |
11 | 2 |
3 import static org.junit.Assert.*; | |
4 | |
5 import java.io.IOException; | |
6 import java.net.BindException; | |
7 import java.net.ServerSocket; | |
8 import java.net.Socket; | |
9 import java.nio.ByteBuffer; | |
10 import java.util.Iterator; | |
11 import java.util.LinkedList; | |
12 | |
13 | |
14 import org.junit.Test; | |
15 | |
19 | 16 import com.glavsoft.exceptions.CommonException; |
15 | 17 import com.glavsoft.exceptions.TransportException; |
18 import com.glavsoft.rfb.encoding.EncodingType; | |
20
98519d16a8c3
getInitData from ProtocolContext
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
19 import com.glavsoft.rfb.protocol.Protocol; |
98519d16a8c3
getInitData from ProtocolContext
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
20 import com.glavsoft.rfb.protocol.ProtocolContext; |
15 | 21 import com.glavsoft.transport.Reader; |
16 | 22 import com.glavsoft.transport.Writer; |
11 | 23 |
24 //import myVncProxy.MulticastQueue.Client; | |
25 | |
26 import java.util.concurrent.ExecutorService; | |
27 import java.util.concurrent.atomic.AtomicInteger; | |
28 import java.util.zip.DataFormatException; | |
29 import java.util.zip.Deflater; | |
30 import java.util.zip.Inflater; | |
31 | |
12 | 32 import jp.ac.u_ryukyu.treevnc.MulticastQueue; |
33 | |
11 | 34 public class MyRfbProtoProxy { |
35 final static String versionMsg_3_855 = "RFB 003.855\n"; | |
36 /** | |
37 * CheckMillis is one of new msgType for RFB 3.855. | |
38 */ | |
39 final static byte SpeedCheckMillis = 4; | |
15 | 40 final static int FramebufferUpdate = 0; |
41 final static int CheckDelay = 11; | |
16 | 42 final static int FramebufferUpdateRequest = 3; |
11 | 43 |
44 // Secyrity type of OS X | |
45 final static int SecTypeReqAccess = 32; | |
46 | |
47 // Supported authentication types | |
48 final static int AuthAccess = 32; | |
49 | |
50 private static final int INFLATE_BUFSIZE = 1024 * 100; | |
51 boolean printStatusFlag = false; | |
52 long startCheckTime; | |
19 | 53 |
11 | 54 |
55 private ServerSocket servSock; | |
56 protected int acceptPort; | |
57 // private byte initData[]; | |
20
98519d16a8c3
getInitData from ProtocolContext
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
58 ProtocolContext context; |
11 | 59 private LinkedList<Socket> cliListTmp; |
60 private LinkedList<Socket> cliList; | |
61 boolean createBimgFlag; | |
62 boolean proxyFlag = true; | |
63 ExecutorService executor; | |
64 | |
65 byte[] pngBytes; | |
66 | |
67 // private MulticastQueue<LinkedList<ByteBuffer>> multicastqueue = new | |
68 // MostRecentMultiCast<LinkedList<ByteBuffer>>(10); | |
69 private MulticastQueue<LinkedList<ByteBuffer>> multicastqueue = new MulticastQueue<LinkedList<ByteBuffer>>(); | |
70 private int clients = 0; | |
71 private Inflater inflater = new Inflater(); | |
72 private Deflater deflater = new Deflater(); | |
73 // private Thread requestThread; | |
74 private RequestScreenThread rThread; | |
75 private Thread requestThread; | |
76 | |
15 | 77 public MyRfbProtoProxy() { |
16 | 78 rThread = new RequestScreenThread(this); |
79 requestThread = new Thread(rThread); | |
11 | 80 } |
81 | |
19 | 82 public void setStream(Writer _writer) { |
23 | 83 // os = _writer; |
15 | 84 } |
11 | 85 |
86 void initServSock(int port) throws IOException { | |
87 servSock = new ServerSocket(port); | |
88 acceptPort = port; | |
89 } | |
90 | |
91 /* | |
92 * default port number is 5999. | |
93 */ | |
94 public void selectPort(int p) { | |
95 if (servSock != null) | |
96 return; | |
97 int port = p; | |
98 while (true) { | |
99 try { | |
100 initServSock(port); | |
101 break; | |
102 } catch (BindException e) { | |
103 port++; | |
104 continue; | |
105 } catch (IOException e) { | |
106 | |
107 } | |
108 } | |
109 System.out.println("accept port = " + port); | |
110 } | |
111 | |
112 int getAcceptPort() { | |
113 return acceptPort; | |
114 } | |
115 | |
116 void setSoTimeout(int num) throws IOException { | |
117 servSock.setSoTimeout(num); | |
118 } | |
119 | |
120 public Socket accept() throws IOException { | |
121 return servSock.accept(); | |
122 } | |
123 | |
124 void addSock(Socket sock) { | |
125 cliList.add(sock); | |
126 } | |
127 | |
128 void addSockTmp(Socket sock) { | |
129 System.out.println("connected " + sock.getInetAddress()); | |
130 cliListTmp.add(sock); | |
131 } | |
132 | |
133 synchronized void changeStatusFlag() { | |
134 printStatusFlag = true; | |
135 } | |
136 | |
137 void printMills() { | |
138 if (printStatusFlag) { | |
139 | |
140 changeStatusFlag(); | |
141 } else { | |
142 changeStatusFlag(); | |
143 } | |
144 } | |
145 | |
146 void requestThreadStart() { | |
147 requestThread.start(); | |
148 } | |
149 | |
150 public synchronized void requestThreadNotify() { | |
151 rThread.reStart(); | |
152 } | |
153 | |
154 /** | |
155 * gzip byte arrays | |
156 * | |
157 * @param deflater | |
158 * @param inputs | |
159 * byte data[] | |
160 * @param inputIndex | |
161 * @param outputs | |
162 * byte data[] | |
163 * @return byte length in last byte array | |
164 * @throws IOException | |
165 */ | |
166 public int zip(Deflater deflater, LinkedList<ByteBuffer> inputs, | |
167 int inputIndex, LinkedList<ByteBuffer> outputs) throws IOException { | |
168 int len = 0; | |
169 ByteBuffer c1 = ByteBuffer.allocate(INFLATE_BUFSIZE); | |
170 while (inputIndex < inputs.size()) { | |
171 ByteBuffer b1 = inputs.get(inputIndex++); | |
172 deflater.setInput(b1.array(), b1.position(), b1.remaining()); | |
173 /** | |
174 * If we finish() stream and reset() it, Deflater start new gzip | |
175 * stream, this makes continuous zlib reader unhappy. if we remove | |
176 * finish(), Deflater.deflate() never flushes its output. The | |
177 * original zlib deflate has flush flag. I'm pretty sure this a kind | |
178 * of bug of Java library. | |
179 */ | |
180 if (inputIndex == inputs.size()) | |
181 deflater.finish(); | |
182 int len1 = 0; | |
183 do { | |
184 len1 = deflater.deflate(c1.array(), c1.position(), | |
185 c1.remaining()); | |
186 if (len1 > 0) { | |
187 len += len1; | |
188 c1.position(c1.position() + len1); | |
189 if (c1.remaining() == 0) { | |
190 c1.flip(); | |
191 outputs.addLast(c1); | |
192 c1 = ByteBuffer.allocate(INFLATE_BUFSIZE); | |
193 } | |
194 } | |
195 } while (len1 > 0 || !deflater.needsInput()); // &&!deflater.finished()); | |
196 } | |
197 if (c1.position() != 0) { | |
198 c1.flip(); | |
199 outputs.addLast(c1); | |
200 } | |
201 deflater.reset(); | |
202 return len; | |
203 } | |
204 | |
205 /** | |
206 * gunzip byte arrays | |
207 * | |
208 * @param inflater | |
209 * @param inputs | |
210 * byte data[] | |
211 * @param outputs | |
212 * byte data[] | |
213 * @return number of total bytes | |
214 * @throws IOException | |
215 */ | |
216 public int unzip(Inflater inflater, LinkedList<ByteBuffer> inputs, | |
217 int inputIndex, LinkedList<ByteBuffer> outputs, int bufSize) | |
218 throws DataFormatException { | |
219 int len = 0; | |
220 ByteBuffer buf = ByteBuffer.allocate(bufSize); | |
221 while (inputIndex < inputs.size()) { | |
222 ByteBuffer input = inputs.get(inputIndex++); | |
223 inflater.setInput(input.array(), input.position(), input.limit()); | |
224 // if (inputIndex==inputs.size()) if inflater/deflater has symmetry, | |
225 // we need this | |
226 // inflater.end(); but this won't work | |
227 do { | |
228 int len0 = inflater.inflate(buf.array(), buf.position(), | |
229 buf.remaining()); | |
230 if (len0 > 0) { | |
231 buf.position(buf.position() + len0); | |
232 len += len0; | |
233 if (buf.remaining() == 0) { | |
234 buf.flip(); | |
235 outputs.addLast(buf); | |
236 buf = ByteBuffer.allocate(bufSize); | |
237 } | |
238 } | |
239 } while (!inflater.needsInput()); | |
240 } | |
241 if (buf.position() != 0) { | |
242 buf.flip(); | |
243 outputs.addLast(buf); | |
244 } | |
245 return len; | |
246 } | |
247 | |
248 float maxMag = 1; | |
249 | |
250 /** | |
251 * send data to clients | |
252 * | |
253 * @param dataLen | |
19 | 254 * @param is |
11 | 255 * @throws IOException |
256 * @throws DataFormatException | |
257 * | |
258 * Zlibed packet is compressed in context dependent way, that | |
259 * is, it have to send from the beginning. But this is | |
260 * impossible. So we have to compress it again for each clients. | |
261 * Separate deflater for each clients is necessary. | |
262 * | |
263 * Java's deflater does not support flush. This means to get the | |
264 * result, we have to finish the compression. Reseting start new | |
265 * compression, but it is not accepted well in zlib continuous | |
266 * reading. So we need new Encoding ZRLEE which reset decoder | |
267 * for each packet. ZRLEE can be invisible from user, but it | |
268 * have to be implemented in the clients. ZRLEE compression is | |
269 * not context dependent, so no recompression is necessary. | |
16 | 270 * @throws TransportException |
11 | 271 */ |
272 | |
19 | 273 public void readSendData(int dataLen, Reader is) throws CommonException { |
11 | 274 LinkedList<ByteBuffer> bufs = new LinkedList<ByteBuffer>(); |
275 ByteBuffer header = ByteBuffer.allocate(16); | |
17 | 276 is.readBytes(header.array(), 0, 16); |
11 | 277 header.limit(16); |
16 | 278 if (header.get(0) == FramebufferUpdate) { |
11 | 279 int encoding = header.getInt(12); |
15 | 280 if (encoding == EncodingType.ZRLE.getId() |
16 | 281 || encoding == EncodingType.ZLIB.getId()) { // ZRLEE is |
282 // already | |
283 // recompressed | |
11 | 284 ByteBuffer len = ByteBuffer.allocate(4); |
17 | 285 is.readBytes(len.array(), 0, 4); |
11 | 286 len.limit(4); |
287 ByteBuffer inputData = ByteBuffer.allocate(dataLen - 20); | |
288 | |
17 | 289 is.readBytes(inputData.array(), 0, inputData.capacity()); |
16 | 290 // System.out.println(dataLen); |
11 | 291 inputData.limit(dataLen - 20); |
292 | |
293 LinkedList<ByteBuffer> inputs = new LinkedList<ByteBuffer>(); | |
294 inputs.add(inputData); | |
295 | |
16 | 296 header.putInt(12, EncodingType.ZRLEE.getId()); // means |
297 // recompress | |
298 // every time | |
11 | 299 // using new Deflecter every time is incompatible with the |
300 // protocol, clients have to be modified. | |
301 Deflater nDeflater = deflater; // new Deflater(); | |
302 LinkedList<ByteBuffer> out = new LinkedList<ByteBuffer>(); | |
19 | 303 int len2 = 0; |
304 try { | |
305 unzip(inflater, inputs, 0, out, INFLATE_BUFSIZE); | |
306 len2 = zip(nDeflater, out, 0, bufs); | |
307 } catch (DataFormatException e) { | |
308 throw new CommonException(e); | |
309 } catch (IOException e) { | |
310 throw new CommonException(e); | |
311 } | |
312 | |
11 | 313 ByteBuffer blen = ByteBuffer.allocate(4); |
314 blen.putInt(len2); | |
315 blen.flip(); | |
316 bufs.addFirst(blen); | |
317 | |
318 bufs.addFirst(header); | |
16 | 319 // if(dataLen<=64000) |
320 multicastqueue.put(bufs); | |
11 | 321 // is.reset(); |
322 | |
323 /* | |
324 * System.out.println("ZRLE = "+dataLen); | |
325 * System.out.println("ZRLEE = "+(len2+20)); float mag = | |
326 * (float)dataLen / (float)(len2 + 20); | |
327 * System.out.println("ZRLE / ZRLEE = "+ mag); if(mag > maxMag) | |
328 * maxMag = mag; System.out.println("maxMag = "+maxMag); | |
329 */ | |
330 return; | |
331 } | |
332 bufs.add(header); | |
333 if (dataLen > 16) { | |
334 ByteBuffer b = ByteBuffer.allocate(dataLen - 16); | |
17 | 335 is.readBytes(b.array(), 0, dataLen - 16); |
11 | 336 b.limit(dataLen - 16); |
337 bufs.add(b); | |
338 } | |
339 multicastqueue.put(bufs); | |
340 // is.reset(); | |
341 return; | |
342 } | |
17 | 343 is.reset(); |
11 | 344 |
345 // It may be compressed. We can inflate here to avoid repeating clients | |
346 // decompressing here, | |
347 // but it may generate too many large data. It is better to do it in | |
348 // each client. | |
349 // But we have do inflation for all input data, so we have to do it | |
350 // here. | |
351 } | |
352 | |
353 public void newClient(AcceptThread acceptThread, final Socket newCli, | |
17 | 354 final Writer os, final Reader is) throws IOException { |
11 | 355 // createBimgFlag = true; |
356 // rfb.addSockTmp(newCli); | |
357 // addSock(newCli); | |
358 final int myId = clients; | |
19 | 359 final MulticastQueue.Client<LinkedList<ByteBuffer>> c = multicastqueue.newClient(); |
11 | 360 final AtomicInteger writerRunning = new AtomicInteger(); |
361 writerRunning.set(1); | |
362 /** | |
363 * Timeout thread. If a client is suspended, it has top of queue | |
364 * indefinitely, which caused memory overflow. After the timeout, we | |
365 * poll the queue and discard it. Start long wait if writer is running. | |
366 */ | |
367 final Runnable timer = new Runnable() { | |
368 public void run() { | |
369 int count = 0; | |
370 for (;;) { | |
371 long timeout = 50000 / 8; | |
372 try { | |
373 synchronized (this) { | |
374 int state, flag; | |
375 writerRunning.set(0); | |
376 wait(timeout); | |
377 flag = 0; | |
378 while ((state = writerRunning.get()) == 0) { | |
379 c.poll(); // discard, should be timeout | |
380 count++; | |
381 if (flag == 0) { | |
382 System.out.println("Discarding " + myId | |
383 + " count=" + count); | |
384 flag = 1; | |
385 } | |
386 wait(10); // if this is too short, writer cannot | |
387 // take the poll, if this is too | |
388 // long, memory will overflow... | |
389 } | |
390 if (flag == 1) | |
391 System.out.println("Resuming " + myId | |
392 + " count=" + count); | |
393 if (state != 1) { | |
394 System.out.println("Client died " + myId); | |
395 break; | |
396 } | |
397 } | |
398 } catch (InterruptedException e) { | |
399 } | |
400 } | |
401 } | |
402 }; | |
403 new Thread(timer).start(); | |
404 /** | |
405 * discard all incoming from clients | |
406 */ | |
407 final Runnable reader = new Runnable() { | |
408 public void run() { | |
409 byte b[] = new byte[4096]; | |
410 for (;;) { | |
411 try { | |
17 | 412 int c = is.readByte(b); |
11 | 413 if (c <= 0) |
414 throw new IOException(); | |
415 // System.out.println("client read "+c); | |
416 } catch (IOException e) { | |
417 try { | |
418 writerRunning.set(2); | |
419 os.close(); | |
420 is.close(); | |
421 } catch (IOException e1) { | |
17 | 422 } catch (TransportException e1) { |
423 e1.printStackTrace(); | |
11 | 424 } |
425 return; | |
17 | 426 } catch (TransportException e) { |
427 e.printStackTrace(); | |
11 | 428 } |
429 } | |
430 } | |
431 }; | |
432 /** | |
433 * send packets to a client | |
434 */ | |
435 Runnable sender = new Runnable() { | |
436 public void run() { | |
437 writerRunning.set(1); | |
438 try { | |
439 requestThreadNotify(); | |
440 // rThread.checkDelay(); | |
441 | |
442 /** | |
443 * initial connection of RFB protocol | |
444 */ | |
445 sendRfbVersion(os); | |
446 // readVersionMsg(is); | |
19 | 447 readVersionMsg(is, os); |
11 | 448 sendSecurityType(os); |
449 readSecType(is); | |
450 sendSecResult(os); | |
451 readClientInit(is); | |
452 sendInitData(os); | |
453 new Thread(reader).start(); // discard incoming packet here | |
454 // after. | |
455 // writeFramebufferUpdateRequest(0,0, framebufferWidth, | |
456 // framebufferHeight, false ); | |
457 for (;;) { | |
458 LinkedList<ByteBuffer> bufs = c.poll(); | |
459 int inputIndex = 0; | |
460 ByteBuffer header = bufs.get(inputIndex); | |
461 if (header == null) | |
462 continue; | |
15 | 463 else if (header.get(0) == CheckDelay) { |
11 | 464 writeToClient(os, bufs, inputIndex); |
465 continue; | |
15 | 466 } else if (header.get(0) == FramebufferUpdate) { |
11 | 467 // System.out.println("client "+ myId); |
468 } | |
469 /* | |
16 | 470 * if(i%20==0){ sendDataCheckDelay(); } i++; |
471 */ | |
11 | 472 writeToClient(os, bufs, inputIndex); |
473 writerRunning.set(1); // yes my client is awaking. | |
474 } | |
475 } catch (IOException e) { | |
476 try { | |
477 writerRunning.set(2); | |
478 os.close(); | |
479 } catch (IOException e1) { | |
480 } | |
481 /* if socket closed cliList.remove(newCli); */ | |
17 | 482 } catch (TransportException e) { |
483 e.printStackTrace(); | |
11 | 484 } |
485 } | |
486 | |
17 | 487 public void writeToClient(final Writer os, |
11 | 488 LinkedList<ByteBuffer> bufs, int inputIndex) |
17 | 489 throws TransportException { |
11 | 490 while (inputIndex < bufs.size()) { |
491 ByteBuffer b = bufs.get(inputIndex++); | |
492 os.write(b.array(), b.position(), b.limit()); | |
493 } | |
494 os.flush(); | |
495 } | |
496 }; | |
497 clients++; | |
498 new Thread(sender).start(); | |
499 | |
500 } | |
501 | |
502 public void dump32(LinkedList<ByteBuffer> bufs) { | |
503 int len = 0; | |
504 for (ByteBuffer b : bufs) | |
505 len += b.remaining(); | |
506 ByteBuffer top = bufs.getFirst(); | |
507 ByteBuffer end = bufs.getLast(); | |
508 System.err.println("length: " + len); | |
509 System.err.print("head 0: "); | |
510 for (int i = 0; i < 16 && i < top.remaining(); i++) { | |
511 System.err.print(" " + top.get(i)); | |
512 } | |
513 System.err.print("tail 0: "); | |
514 for (int i = 0; i < 16 && i < end.remaining(); i++) { | |
515 System.err.print(" " + end.get(i)); | |
516 } | |
517 System.err.println(); | |
518 } | |
519 | |
520 @Test | |
521 public void test1() { | |
522 try { | |
523 LinkedList<ByteBuffer> in = new LinkedList<ByteBuffer>(); | |
524 LinkedList<ByteBuffer> out = new LinkedList<ByteBuffer>(); | |
525 LinkedList<ByteBuffer> out2 = new LinkedList<ByteBuffer>(); | |
526 // if (false) { | |
527 // for(int i=0;i<10;i++) { | |
528 // in.add(ByteBuffer.wrap("test1".getBytes())); | |
529 // in.add(ByteBuffer.wrap("test2".getBytes())); | |
530 // in.add(ByteBuffer.wrap("test3".getBytes())); | |
531 // in.add(ByteBuffer.wrap("test44".getBytes())); | |
532 // } | |
533 // } else | |
534 { | |
535 String t = ""; | |
536 for (int i = 0; i < 10; i++) { | |
537 t += "test1"; | |
538 t += "test2"; | |
539 t += "test3"; | |
540 t += "test44"; | |
541 } | |
542 in.add(ByteBuffer.wrap(t.getBytes())); | |
543 } | |
544 | |
545 LinkedList<ByteBuffer> in1 = clone(in); | |
546 | |
547 Deflater deflater = new Deflater(); | |
548 zip(deflater, in, 0, out); | |
549 // LinkedList<ByteBuffer> out3 = clone(out); zipped result is depend | |
550 // on deflator's state | |
551 unzip(inflater, out, 0, out2, INFLATE_BUFSIZE); | |
552 // inflater.reset(); | |
553 equalByteBuffers(in1, out2); | |
554 LinkedList<ByteBuffer> out4 = new LinkedList<ByteBuffer>(); | |
555 deflater = new Deflater(); | |
556 zip(deflater, out2, 0, out4); | |
557 LinkedList<ByteBuffer> out5 = new LinkedList<ByteBuffer>(); | |
558 unzip(inflater, out4, 0, out5, INFLATE_BUFSIZE); | |
559 int len = equalByteBuffers(in1, out5); | |
560 | |
561 System.out.println("Test Ok. " + len); | |
562 } catch (Exception e) { | |
563 assertEquals(0, 1); | |
564 } | |
565 } | |
566 | |
567 private LinkedList<ByteBuffer> clone(LinkedList<ByteBuffer> in) { | |
568 LinkedList<ByteBuffer> copy = new LinkedList<ByteBuffer>(); | |
569 for (ByteBuffer b : in) { | |
570 ByteBuffer c = b.duplicate(); | |
571 copy.add(c); | |
572 } | |
573 return copy; | |
574 } | |
575 | |
576 public int equalByteBuffers(LinkedList<ByteBuffer> in, | |
577 LinkedList<ByteBuffer> out2) { | |
578 int len = 0; | |
579 Iterable<Byte> i = byteBufferIterator(in); | |
580 Iterator<Byte> o = byteBufferIterator(out2).iterator(); | |
581 | |
582 for (int b : i) { | |
583 len++; | |
584 if (o.hasNext()) { | |
585 int c = o.next(); | |
586 assertEquals(b, c); | |
587 } else | |
588 assertEquals(0, 1); | |
589 } | |
590 if (o.hasNext()) | |
591 assertEquals(0, 1); | |
592 // System.out.println(); | |
593 return len; | |
594 } | |
595 | |
596 private Iterable<Byte> byteBufferIterator(final LinkedList<ByteBuffer> in) { | |
597 return new Iterable<Byte>() { | |
598 public Iterator<Byte> iterator() { | |
599 return new Iterator<Byte>() { | |
600 int bytes = 0; | |
601 int buffers = 0; | |
602 | |
603 public boolean hasNext() { | |
604 for (;;) { | |
605 if (buffers >= in.size()) | |
606 return false; | |
607 ByteBuffer b = in.get(buffers); | |
608 if (!(bytes < b.remaining())) { | |
609 buffers++; | |
610 bytes = 0; | |
611 } else | |
612 return true; | |
613 } | |
614 } | |
615 | |
616 public Byte next() { | |
617 ByteBuffer bf = in.get(buffers); | |
618 byte b = bf.get(bytes++); | |
619 if (bf.remaining() <= bytes) { | |
620 buffers++; | |
621 bytes = 0; | |
622 } | |
623 // System.out.print(b); | |
624 return b; | |
625 } | |
626 | |
627 public void remove() { | |
628 } | |
629 }; | |
630 } | |
631 }; | |
632 } | |
16 | 633 |
17 | 634 void sendRfbVersion(Writer writer) throws IOException, TransportException { |
15 | 635 // os.write(versionMsg_3_8.getBytes()); |
17 | 636 writer.write(versionMsg_3_855.getBytes()); |
15 | 637 } |
16 | 638 |
17 | 639 int readVersionMsg(Reader reader, Writer writer) throws IOException, TransportException { |
11 | 640 |
15 | 641 byte[] b = new byte[12]; |
642 | |
17 | 643 reader.readBytes(b); |
15 | 644 |
645 if ((b[0] != 'R') || (b[1] != 'F') || (b[2] != 'B') || (b[3] != ' ') | |
646 || (b[4] < '0') || (b[4] > '9') || (b[5] < '0') || (b[5] > '9') | |
647 || (b[6] < '0') || (b[6] > '9') || (b[7] != '.') | |
648 || (b[8] < '0') || (b[8] > '9') || (b[9] < '0') || (b[9] > '9') | |
649 || (b[10] < '0') || (b[10] > '9') || (b[11] != '\n')) { | |
650 throw new IOException("this is not an RFB server"); | |
651 } | |
652 | |
653 int rfbMajor = (b[4] - '0') * 100 + (b[5] - '0') * 10 + (b[6] - '0'); | |
654 int rfbMinor = (b[8] - '0') * 100 + (b[9] - '0') * 10 + (b[10] - '0'); | |
655 | |
656 if (rfbMajor < 3) { | |
657 throw new IOException( | |
658 "RFB server does not support protocol version 3"); | |
659 } | |
660 | |
661 if (rfbMinor == 855) { | |
17 | 662 sendProxyFlag(writer); |
15 | 663 if (proxyFlag) |
17 | 664 sendPortNumber(writer); |
15 | 665 } |
666 return rfbMinor; | |
667 } | |
16 | 668 |
17 | 669 void sendProxyFlag(Writer writer) throws TransportException { |
15 | 670 if (proxyFlag) |
17 | 671 writer.writeInt(1); |
15 | 672 else |
17 | 673 writer.writeInt(0); |
15 | 674 } |
16 | 675 |
17 | 676 void sendPortNumber(Writer writer) throws TransportException { |
15 | 677 byte[] b = new byte[4]; |
17 | 678 //b = castIntByte(getHost.getPort()); |
679 b = castIntByte(9999); | |
680 writer.write(b); | |
15 | 681 } |
682 | |
17 | 683 void sendSecurityType(Writer os) throws TransportException { |
15 | 684 // number-of-security-types |
17 | 685 os.writeInt(1); |
15 | 686 // security-types |
687 // 1:None | |
17 | 688 os.writeInt(1); |
15 | 689 |
690 /* | |
691 * os.write(4); os.write(30); os.write(31); os.write(32); os.write(35); | |
692 * os.flush(); | |
693 */ | |
694 } | |
695 | |
17 | 696 void readSecType(Reader reader) throws TransportException { |
15 | 697 byte[] b = new byte[1]; |
17 | 698 reader.read(b); |
15 | 699 } |
700 | |
17 | 701 void readSecType(Reader is, Writer os) throws TransportException { |
15 | 702 byte[] b = new byte[1]; |
17 | 703 is.readBytes(b); |
15 | 704 |
705 int count = 260; | |
706 int[] data = { 0, 2, 0, -128, -1, -1, -1, -1, -1, -1, -1, -1, -55, 15, | |
707 -38, -94, 33, 104, -62, 52, -60, -58, 98, -117, -128, -36, 28, | |
708 -47, 41, 2, 78, 8, -118, 103, -52, 116, 2, 11, -66, -90, 59, | |
709 19, -101, 34, 81, 74, 8, 121, -114, 52, 4, -35, -17, -107, 25, | |
710 -77, -51, 58, 67, 27, 48, 43, 10, 109, -14, 95, 20, 55, 79, | |
711 -31, 53, 109, 109, 81, -62, 69, -28, -123, -75, 118, 98, 94, | |
712 126, -58, -12, 76, 66, -23, -90, 55, -19, 107, 11, -1, 92, -74, | |
713 -12, 6, -73, -19, -18, 56, 107, -5, 90, -119, -97, -91, -82, | |
714 -97, 36, 17, 124, 75, 31, -26, 73, 40, 102, 81, -20, -26, 83, | |
715 -127, -1, -1, -1, -1, -1, -1, -1, -1, -111, 73, -29, 30, 57, | |
716 -67, -75, -77, -49, -50, -99, -76, -80, -80, 14, 65, 57, -105, | |
717 -103, -54, -102, 3, 39, -44, 39, 35, 118, -84, -64, 37, -117, | |
718 -21, 89, -31, -68, 70, 5, 122, -92, -119, 9, 121, 63, -112, | |
719 -60, 122, -46, -69, -36, 92, -103, -92, 74, 92, -73, 87, 120, | |
720 -8, 116, -47, 111, 20, -41, 110, 122, -3, -94, 14, 42, -51, | |
721 -59, 48, -54, -125, 117, 60, 77, -52, -31, 98, 32, -2, -102, | |
722 -15, -29, 58, -14, -106, -116, -32, -86, 50, -32, -16, -3, | |
723 -123, 87, 88, -118, 10, 120, -107, -37, 125, -110, 59, 87, 93, | |
724 -24, 124, -99, 18, 78, -13, -49, -34, -24, -27, 1, 114, -67, | |
725 -98, -56, -3, 85, -67, -126, 77 }; | |
726 for (int i = 0; i < count; i++) { | |
727 os.write((byte) data[i]); | |
728 os.flush(); | |
729 } | |
730 | |
731 byte[] c = new byte[256]; | |
17 | 732 is.readBytes(c); |
15 | 733 |
734 System.out.println(new String(c)); | |
735 | |
736 } | |
737 | |
17 | 738 void sendSecResult(Writer os) throws TransportException { |
15 | 739 byte[] b = castIntByte(0); |
740 os.write(b); | |
741 } | |
16 | 742 |
15 | 743 byte[] castIntByte(int len) { |
744 byte[] b = new byte[4]; | |
745 b[0] = (byte) ((len >>> 24) & 0xFF); | |
746 b[1] = (byte) ((len >>> 16) & 0xFF); | |
747 b[2] = (byte) ((len >>> 8) & 0xFF); | |
748 b[3] = (byte) ((len >>> 0) & 0xFF); | |
749 return b; | |
750 } | |
751 | |
17 | 752 void readClientInit(Reader in) throws TransportException { |
15 | 753 byte[] b = new byte[0]; |
17 | 754 in.readBytes(b); |
15 | 755 } |
756 | |
17 | 757 void sendInitData(Writer os) throws TransportException { |
20
98519d16a8c3
getInitData from ProtocolContext
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
758 os.write(context.getInitData()); |
15 | 759 } |
16 | 760 |
19 | 761 public void writeFramebufferUpdateRequest(int x, int y, int w, int h, |
17 | 762 boolean incremental) throws TransportException { |
16 | 763 byte[] b = new byte[10]; |
764 | |
765 b[0] = (byte) FramebufferUpdateRequest; | |
766 b[1] = (byte) (incremental ? 1 : 0); | |
767 b[2] = (byte) ((x >> 8) & 0xff); | |
768 b[3] = (byte) (x & 0xff); | |
769 b[4] = (byte) ((y >> 8) & 0xff); | |
770 b[5] = (byte) (y & 0xff); | |
771 b[6] = (byte) ((w >> 8) & 0xff); | |
772 b[7] = (byte) (w & 0xff); | |
773 b[8] = (byte) ((h >> 8) & 0xff); | |
774 b[9] = (byte) (h & 0xff); | |
775 | |
23 | 776 // os.write(b); |
16 | 777 } |
20
98519d16a8c3
getInitData from ProtocolContext
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
778 |
98519d16a8c3
getInitData from ProtocolContext
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
779 public void setProtocolContext(Protocol workingProtocol) { |
98519d16a8c3
getInitData from ProtocolContext
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
780 context = workingProtocol; |
98519d16a8c3
getInitData from ProtocolContext
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
781 } |
18 | 782 |
11 | 783 } |