# HG changeset patch # User Shinji KONO # Date 1312309239 -32400 # Node ID 9109273b96dc96c94d68cf8e905959a2f2f7496f # Parent 712a047908df01f74199b4e5abcad1e7f67b97e2 consume too much memory diff -r 712a047908df -r 9109273b96dc src/myVncProxy/MyRfbProto.java --- a/src/myVncProxy/MyRfbProto.java Wed Aug 03 02:42:56 2011 +0900 +++ b/src/myVncProxy/MyRfbProto.java Wed Aug 03 03:20:39 2011 +0900 @@ -32,7 +32,7 @@ * CheckMillis is one of new msgType for RFB 3.998. */ final static int SpeedCheckMillis = 4; - private static final int INFLATE_BUFSIZE = 1024*1024; + private static final int INFLATE_BUFSIZE = 1024*1024*16; boolean printStatusFlag = false; long startCheckTime; @@ -59,6 +59,7 @@ private MulticastQueue multicastqueue = new MulticastQueue(); private int clients = 0; + private Inflater inflater = new Inflater(); MyRfbProto(String h, int p, VncViewer v) throws IOException { super(h, p, v); @@ -370,14 +371,33 @@ return dataLen; } - void readSendData(int dataLen) throws IOException { - byte buffer[] = new byte[dataLen]; - readFully(buffer); - multicastqueue.put(buffer); + void readSendData(int dataLen) throws IOException, DataFormatException { + byte b[] = new byte[dataLen]; + readFully(b); + + if (b[0]==RfbProto.FramebufferUpdate) { + int encoding = ((b[12]*256+b[13])*256+b[14])*256+b[15]; + if (encoding==RfbProto.EncodingZlib||encoding==RfbProto.EncodingZRLE) { + byte inf[] = new byte[INFLATE_BUFSIZE]; + inflater.setInput(b, 20, b.length-20); + int len = inflater.inflate(inf,20,inf.length-20); + if (len==INFLATE_BUFSIZE) throw new DataFormatException(); // too large + for(int i = 0;i<20;i++) inf[i] = b[i]; + inf[16+0] = (byte) ((len >>> 24) & 0xFF); + inf[16+1] = (byte) ((len >>> 16) & 0xFF); + inf[16+2] = (byte) ((len >>> 8) & 0xFF); + inf[16+3] = (byte) ((len >>> 0) & 0xFF); + multicastqueue.put(inf); + is.reset(); + return; + } + } + multicastqueue.put(b); is.reset(); // It may be compressed. We can inflate here to avoid repeating clients decompressing here, // but it may generate too many large data. It is better to do it in each client. + // But we have do inflation for all input data, so we have to do it here. /* for (Socket cli : cliList) { try { @@ -393,7 +413,7 @@ } */ } - void sendDataToClient() throws IOException { + void sendDataToClient() throws Exception { regiFramebufferUpdate(); int dataLen = checkAndMark(); readSendData(dataLen); @@ -518,7 +538,6 @@ public void run() { Deflater deflater = new Deflater(); - Inflater inflater = new Inflater(); try { /** * initial connection of RFB protocol @@ -536,15 +555,12 @@ if (b[0]==RfbProto.FramebufferUpdate) { int encoding = ((b[12]*256+b[13])*256+b[14])*256+b[15]; if (encoding==RfbProto.EncodingZlib||encoding==RfbProto.EncodingZRLE) { - byte inf[] = new byte[INFLATE_BUFSIZE]; - inflater.setInput(inf, 0, b.length-24); - int inflen = inflater.inflate(inf); - if (inflen==INFLATE_BUFSIZE) throw new DataFormatException(); // too large byte[] c = new byte[INFLATE_BUFSIZE]; - deflater.setInput(inf,0,inflen); + int clen = ((b[16]*256+b[17])*256+b[18])*256+b[19]; + deflater.setInput(b,20,clen); int len = deflater.deflate(c); byte[] blen = castIntByte(len); - os.write(b,0,20); + os.write(b,0,16); os.write(blen,0,4); os.write(c,0,len); } @@ -556,8 +572,6 @@ * if socket closed */ // cliList.remove(newCli); - } catch (DataFormatException e) { - // should print some error } }