comparison src/myVncProxy/MyRfbProto.java @ 90:462bca4c8cec

ByteBuffer
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Wed, 03 Aug 2011 10:30:45 +0900
parents 9b3b1e3e7db5
children 4116c19cd76e
comparison
equal deleted inserted replaced
89:43822a70978c 90:462bca4c8cec
13 import java.io.InputStream; 13 import java.io.InputStream;
14 import java.io.InputStreamReader; 14 import java.io.InputStreamReader;
15 import java.net.BindException; 15 import java.net.BindException;
16 import java.net.ServerSocket; 16 import java.net.ServerSocket;
17 import java.net.Socket; 17 import java.net.Socket;
18 import java.nio.ByteBuffer;
18 import java.util.LinkedList; 19 import java.util.LinkedList;
19 20
20 import javax.imageio.ImageIO; 21 import javax.imageio.ImageIO;
21 22
22 import org.junit.Test; 23 import org.junit.Test;
34 class MyRfbProto extends RfbProto { 35 class MyRfbProto extends RfbProto {
35 final static String versionMsg_3_998 = "RFB 003.998\n"; 36 final static String versionMsg_3_998 = "RFB 003.998\n";
36 /** 37 /**
37 * CheckMillis is one of new msgType for RFB 3.998. 38 * CheckMillis is one of new msgType for RFB 3.998.
38 */ 39 */
39 final static int SpeedCheckMillis = 4; 40 final static byte SpeedCheckMillis = 4;
40 private static final int INFLATE_BUFSIZE = 1024*100; 41 private static final int INFLATE_BUFSIZE = 1024*100;
41 boolean printStatusFlag = false; 42 boolean printStatusFlag = false;
42 long startCheckTime; 43 long startCheckTime;
43 44
44 private int messageType; 45 private int messageType;
60 61
61 ExecutorService executor; 62 ExecutorService executor;
62 63
63 byte[] pngBytes; 64 byte[] pngBytes;
64 65
65 private MulticastQueue<LinkedList<byte[]>> multicastqueue = new MostRecentMultiCast<LinkedList<byte[]>>(10); 66 private MulticastQueue<LinkedList<ByteBuffer>> multicastqueue = new MostRecentMultiCast<LinkedList<ByteBuffer>>(10);
66 private int clients = 0; 67 private int clients = 0;
67 private Inflater inflater = new Inflater(); 68 private Inflater inflater = new Inflater();
68 69
69 public 70 public
70 MyRfbProto() throws IOException { 71 MyRfbProto() throws IOException {
462 byte[] b = new byte[1]; 463 byte[] b = new byte[1];
463 readFully(b); 464 readFully(b);
464 } 465 }
465 466
466 void startSpeedCheck() { 467 void startSpeedCheck() {
467 byte[] b = new byte[2]; 468 ByteBuffer b = ByteBuffer.allocate(10);
468 b[0] = (byte) SpeedCheckMillis; 469 b.put((byte)SpeedCheckMillis);
469 b[1] = (byte) 0; 470 b.flip();
470 startCheckTime = System.currentTimeMillis(); 471 startCheckTime = System.currentTimeMillis();
471 System.out.println("startChckTime = "+ startCheckTime); 472 System.out.println("startChckTime = "+ startCheckTime);
472 LinkedList<byte[]>bufs = new LinkedList<byte[]>(); 473 LinkedList<ByteBuffer>bufs = new LinkedList<ByteBuffer>();
473 bufs.add(b); 474 bufs.add(b);
474 multicastqueue.put(bufs); 475 multicastqueue.put(bufs);
475 } 476 }
476 477
477 void endSpeedCheck() { 478 void endSpeedCheck() {
530 * byte len[4] total byte length 531 * byte len[4] total byte length
531 * byte data[] 532 * byte data[]
532 * @return byte length in last byte array 533 * @return byte length in last byte array
533 * @throws IOException 534 * @throws IOException
534 */ 535 */
535 public int zip(Deflater deflater,LinkedList<byte[]> inputs, LinkedList<byte[]> outputs) throws IOException { 536 public int zip(Deflater deflater,LinkedList<ByteBuffer> inputs, LinkedList<ByteBuffer> outputs) throws IOException {
536 int clen = u32(inputs.poll(),0); 537 int len1=0,len = 0;
537 int len = 0, count = 0;
538 int len2=0;
539 deflater.reset(); 538 deflater.reset();
540 do { 539 do {
541 byte[] b1 = inputs.poll(); 540 ByteBuffer b1 = inputs.poll();
541 deflater.setInput(b1.array(),b1.position(),b1.limit());
542 if (inputs.size()==0) { 542 if (inputs.size()==0) {
543 deflater.setInput(b1,0,clen);
544 deflater.finish(); 543 deflater.finish();
545 } else { 544 }
546 deflater.setInput(b1);
547 clen -= b1.length;
548 }
549 int len1=0;
550 do { 545 do {
551 byte[] c1 = new byte[INFLATE_BUFSIZE]; 546 ByteBuffer c1 = ByteBuffer.allocate(INFLATE_BUFSIZE);
552 len2 = len1; 547 len1 = deflater.deflate(c1.array(),c1.position(),c1.capacity());
553 len1 = deflater.deflate(c1); 548 c1.limit(len1);
554 if (len1>0) { 549 if (len1>0) {
555 outputs.addLast(c1); 550 outputs.addLast(c1);
556 count ++;
557 len += len1; 551 len += len1;
558 } 552 }
559 } while (len1 > 0); 553 } while (len1 > 0);
560 } while(inputs.size()>0); 554 } while(inputs.size()>0);
561 byte[] blen = castIntByte(len); 555 ByteBuffer blen = ByteBuffer.wrap(castIntByte(len));
562 outputs.addFirst(blen); 556 outputs.addFirst(blen);
563 return len2; 557 return len;
564 } 558 }
565 559
566 /** 560 /**
567 * gunzip byte arrays 561 * gunzip byte arrays
568 * @param inflater 562 * @param inflater
572 * @param outputs 566 * @param outputs
573 * byte len[4] total byte length 567 * byte len[4] total byte length
574 * byte data[] 568 * byte data[]
575 * @throws IOException 569 * @throws IOException
576 */ 570 */
577 public void unzip(Inflater inflater, LinkedList<byte[]> inputs, LinkedList<byte[]> outputs) 571 public int unzip(Inflater inflater, LinkedList<ByteBuffer> inputs, LinkedList<ByteBuffer> outputs)
578 throws DataFormatException { 572 throws DataFormatException {
579 int len=0,len0; 573 int len=0,len0;
580 inputs.poll(); 574 do {
581 for(byte [] input:inputs) { 575 ByteBuffer input = inputs.poll();
582 inflater.setInput(input); 576 inflater.setInput(input.array(),0,input.limit());
583 do { 577 do {
584 byte buf[] = new byte[INFLATE_BUFSIZE]; 578 ByteBuffer buf = ByteBuffer.allocate(INFLATE_BUFSIZE);
585 len0 = inflater.inflate(buf); 579 len0 = inflater.inflate(buf.array(),0,buf.capacity());
580 buf.limit(len0);
586 len += len0; 581 len += len0;
587 outputs.addLast(buf); 582 outputs.addLast(buf);
588 } while (len0 ==INFLATE_BUFSIZE); 583 } while (len0 ==INFLATE_BUFSIZE);
589 } 584 } while (!inputs.isEmpty());
590 byte [] blen = castIntByte(len); 585 return len;
591 outputs.addFirst(blen);
592 } 586 }
593 587
594 void readSendData(int dataLen) throws IOException, DataFormatException { 588 void readSendData(int dataLen) throws IOException, DataFormatException {
595 LinkedList<byte[]>bufs = new LinkedList<byte[]>(); 589 LinkedList<ByteBuffer>bufs = new LinkedList<ByteBuffer>();
596 byte header[] = new byte[16]; 590 ByteBuffer header = ByteBuffer.allocate(16);
597 readFully(header,0,16); 591 readFully(header.array(),0,16);
598 if (header[0]==RfbProto.FramebufferUpdate) { 592 header.limit(16);
599 int encoding = u32(header,12); 593 if (header.get(0)==RfbProto.FramebufferUpdate) {
594 int encoding = header.getInt(12);
600 if (encoding==RfbProto.EncodingZlib||encoding==RfbProto.EncodingZRLE) { 595 if (encoding==RfbProto.EncodingZlib||encoding==RfbProto.EncodingZRLE) {
601 byte[] len = new byte[4]; 596 ByteBuffer len = ByteBuffer.allocate(4);
602 readFully(len,0,4); 597 readFully(len.array(),0,4); len.limit(4);
603 byte inputData[] = new byte[dataLen-20]; 598 ByteBuffer inputData = ByteBuffer.allocate(dataLen-20);
604 readFully(inputData); 599 readFully(inputData.array(),0,inputData.capacity()); inputData.limit(dataLen-20);
605 LinkedList<byte[]>inputs = new LinkedList<byte[]>(); 600 LinkedList<ByteBuffer>inputs = new LinkedList<ByteBuffer>();
606 inputs.add(len);
607 inputs.add(inputData); 601 inputs.add(inputData);
608 unzip(inflater, inputs, bufs); 602 unzip(inflater, inputs, bufs);
609 bufs.addFirst(header); 603 bufs.addFirst(header);
610 multicastqueue.put(bufs); 604 multicastqueue.put(bufs);
611 is.reset(); 605 is.reset();
612 return ; 606 return ;
613 } 607 }
614 } 608 }
615 bufs.add(header); 609 bufs.add(header);
616 if (dataLen>16) { 610 if (dataLen>16) {
617 byte b[] = new byte[dataLen-16]; 611 ByteBuffer b = ByteBuffer.allocate(dataLen-16);
618 readFully(b); 612 readFully(b.array(),0,dataLen-16); b.limit(dataLen-16);
619 bufs.add(b); 613 bufs.add(b);
620 } 614 }
621 multicastqueue.put(bufs); 615 multicastqueue.put(bufs);
622 is.reset(); 616 is.reset();
623 617
629 void newClient(AcceptThread acceptThread, final Socket newCli, 623 void newClient(AcceptThread acceptThread, final Socket newCli,
630 final OutputStream os, final InputStream is) throws IOException { 624 final OutputStream os, final InputStream is) throws IOException {
631 // createBimgFlag = true; 625 // createBimgFlag = true;
632 // rfb.addSockTmp(newCli); 626 // rfb.addSockTmp(newCli);
633 // addSock(newCli); 627 // addSock(newCli);
634 final Client <LinkedList<byte[]>> c = multicastqueue.newClient(); 628 final Client <LinkedList<ByteBuffer>> c = multicastqueue.newClient();
635 Runnable sender = new Runnable() { 629 Runnable sender = new Runnable() {
636 public void run() { 630 public void run() {
637 631
638 Deflater deflater = new Deflater(); 632 Deflater deflater = new Deflater();
639 try { 633 try {
647 sendSecResult(os); 641 sendSecResult(os);
648 readClientInit(is); 642 readClientInit(is);
649 sendInitData(os); 643 sendInitData(os);
650 644
651 for (;;) { 645 for (;;) {
652 LinkedList<byte[]> bufs = c.poll(); 646 LinkedList<ByteBuffer> bufs = c.poll();
653 byte[] header = bufs.poll(); 647 ByteBuffer header = bufs.poll();
654 if (header[0]==RfbProto.FramebufferUpdate) { 648 if (header.get(0)==RfbProto.FramebufferUpdate) {
655 int encoding = u32(header,12); 649 int encoding = header.getInt(12);
656 if (encoding==RfbProto.EncodingZlib||encoding==RfbProto.EncodingZRLE) { 650 if (encoding==RfbProto.EncodingZlib||encoding==RfbProto.EncodingZRLE) {
657 LinkedList<byte[]> outs = new LinkedList<byte[]>(); 651 LinkedList<ByteBuffer> outs = new LinkedList<ByteBuffer>();
658 int len2 = zip(deflater, bufs, outs); 652 int len2 = zip(deflater, bufs, outs);
653 ByteBuffer blen = ByteBuffer.allocate(4); blen.putInt(len2); blen.flip();
654 outs.addFirst(blen);
659 outs.addFirst(header); 655 outs.addFirst(header);
660 while(!outs.isEmpty()) { 656 while(!outs.isEmpty()) {
661 byte [] out= outs.poll(); 657 ByteBuffer out= outs.poll();
662 if (outs.isEmpty()) 658 os.write(out.array(),out.position(),out.limit());
663 os.write(out,0,len2);
664 else
665 os.write(out);
666 } 659 }
667 } 660 }
668 os.flush(); 661 os.flush();
669 return; 662 return;
670 } 663 }
671 os.write(header); 664 os.write(header.array(),header.position(),header.limit());
672 for(byte [] b : bufs) { 665 for(ByteBuffer b : bufs) {
673 os.write(b, 0, b.length); 666 os.write(b.array(), b.position(), b.limit());
674 } 667 }
675 os.flush(); 668 os.flush();
676 } 669 }
677 } catch (IOException e) { 670 } catch (IOException e) {
678 /* if socket closed cliList.remove(newCli); */ 671 /* if socket closed cliList.remove(newCli); */
682 clients++; 675 clients++;
683 new Thread(sender).start(); 676 new Thread(sender).start();
684 677
685 } 678 }
686 679
687 private int u32(byte[] b, int i) {
688 int ret = 0;
689 for(int j = 0;j<4;j++) {
690 ret *= 256;
691 ret += b[i+j] & 0xff;
692 }
693 return ret;
694 }
695 680
696 681
697 @Test 682 @Test
698 public void test1() { 683 public void test1() {
699 try { 684 try {
700 LinkedList<byte[]> in = new LinkedList<byte[]>(); 685 LinkedList<ByteBuffer> in = new LinkedList<ByteBuffer>();
701 LinkedList<byte[]> out = new LinkedList<byte[]>(); 686 LinkedList<ByteBuffer> out = new LinkedList<ByteBuffer>();
702 LinkedList<byte[]> out2 = new LinkedList<byte[]>(); 687 LinkedList<ByteBuffer> out2 = new LinkedList<ByteBuffer>();
703 for(int i=0;i<10;i++) { 688 for(int i=0;i<10;i++) {
704 in.add("test1".getBytes()); 689 in.add(ByteBuffer.wrap("test1".getBytes()));
705 in.add("test1".getBytes()); 690 in.add(ByteBuffer.wrap("test2".getBytes()));
706 in.add("test1".getBytes()); 691 in.add(ByteBuffer.wrap("test3".getBytes()));
707 in.add("test1".getBytes()); 692 in.add(ByteBuffer.wrap("test4".getBytes()));
708 } 693 }
709 int len = 0; 694
710 for(byte[] b: in) len += b.length;
711 in.addFirst(castIntByte(len));
712
713 Deflater deflater = new Deflater(); 695 Deflater deflater = new Deflater();
714 zip(deflater, in,out); 696 zip(deflater, in,out);
715 unzip(inflater, out, out2); 697 unzip(inflater, out, out2);
716 for(byte[] b:out) { 698 for(ByteBuffer b:out) {
717 byte []c = out2.poll(); 699 ByteBuffer c = out2.poll();
718 assertEquals(b,c); 700 assertEquals(b,c);
719 } 701 }
720 System.out.println("Test Ok."); 702 System.out.println("Test Ok.");
721 } catch (Exception e) { 703 } catch (Exception e) {
722 assertEquals(0,1); 704 assertEquals(0,1);