changeset 81:9109273b96dc

consume too much memory
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Wed, 03 Aug 2011 03:20:39 +0900
parents 712a047908df
children 0cbe556e2c54
files src/myVncProxy/MyRfbProto.java
diffstat 1 files changed, 29 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- 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<byte[]> multicastqueue = new MulticastQueue<byte[]>();
 	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
 				}
 
 			}