# HG changeset patch # User Shinji KONO # Date 1312306976 -32400 # Node ID 712a047908df01f74199b4e5abcad1e7f67b97e2 # Parent 5970410efee71717e7dd9816b2124e6cb78d367d recompress output diff -r 5970410efee7 -r 712a047908df src/myVncProxy/AcceptThread.java --- a/src/myVncProxy/AcceptThread.java Fri Jul 29 19:17:31 2011 +0900 +++ b/src/myVncProxy/AcceptThread.java Wed Aug 03 02:42:56 2011 +0900 @@ -7,13 +7,19 @@ public class AcceptThread implements Runnable { MyRfbProto rfb; byte[] imageBytes; - + int port; + AcceptThread(MyRfbProto _rfb) { rfb = _rfb; } + AcceptThread(MyRfbProto _rfb, int p) { + rfb = _rfb; + port = p; + } + public void run() { - rfb.selectPort(); + rfb.selectPort(port); while (true) { try { Socket newCli = rfb.accept(); diff -r 5970410efee7 -r 712a047908df src/myVncProxy/MyRfbProto.java --- a/src/myVncProxy/MyRfbProto.java Fri Jul 29 19:17:31 2011 +0900 +++ b/src/myVncProxy/MyRfbProto.java Wed Aug 03 02:42:56 2011 +0900 @@ -21,6 +21,9 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.zip.DataFormatException; +import java.util.zip.Deflater; +import java.util.zip.Inflater; import java.io.OutputStream; class MyRfbProto extends RfbProto { @@ -29,6 +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; boolean printStatusFlag = false; long startCheckTime; @@ -54,6 +58,7 @@ byte[] pngBytes; private MulticastQueue multicastqueue = new MulticastQueue(); + private int clients = 0; MyRfbProto(String h, int p, VncViewer v) throws IOException { super(h, p, v); @@ -104,20 +109,20 @@ } // 5550を開けるが、開いてないなら+1のポートを開ける。 - void selectPort() { - int i = 5550; + void selectPort(int p) { + int port = p; while (true) { try { - initServSock(i); + initServSock(port); break; } catch (BindException e) { - i++; + port++; continue; } catch (IOException e) { } } - System.out.println("accept port = " + i); + System.out.println("accept port = " + port); } int getAcceptPort() { @@ -248,20 +253,6 @@ os.write(initData); } - void sendData(byte b[]) { - try { - multicastqueue.put(b); - - /* - * // for(Socket cli : cliList){ // try{ // - * cli.getOutputStream().write(b, 0, b.length); // - * }catch(IOException e){ // // if socket closed // - * cliList.remove(cli); // } // } - */ - // System.out.println("cliSize="+cliSize()); - } catch (Exception e) { - } - } void sendPngImage() { try { @@ -293,30 +284,23 @@ System.out.println("numBytesRead=" + numBytesRead); } - void bufResetSend(int size) throws IOException { - is.reset(); - int len = size; - if (available() < size) - len = available(); - byte buffer[] = new byte[len]; - readFully(buffer); - sendData(buffer); - } void regiFramebufferUpdate() throws IOException { is.mark(20); - messageType = readU8(); - skipBytes(1); - rectangles = readU16(); - rectX = readU16(); - rectY = readU16(); - rectW = readU16(); - rectH = readU16(); - encoding = readU32(); + messageType = readU8(); // 0 + skipBytes(1); // 1 + rectangles = readU16(); // 2 + rectX = readU16(); // 4 + rectY = readU16(); // 6 + rectW = readU16(); // 8 + rectH = readU16(); // 10 + encoding = readU32(); // 12 System.out.println("encoding = "+encoding); - if (encoding == 16) + if (encoding == EncodingZRLE) zLen = readU32(); + else + zLen = 0; is.reset(); /* int dataLen; @@ -362,8 +346,11 @@ case RfbProto.EncodingRRE: case RfbProto.EncodingCoRRE: case RfbProto.EncodingHextile: + case RfbProto.EncodingTight: + dataLen = zLen + 20; + is.mark(dataLen); + break; case RfbProto.EncodingZlib: - case RfbProto.EncodingTight: case RfbProto.EncodingZRLE: dataLen = zLen + 20; is.mark(dataLen); @@ -389,6 +376,8 @@ multicastqueue.put(buffer); 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. /* for (Socket cli : cliList) { try { @@ -527,6 +516,9 @@ final Client c = multicastqueue.newClient(); Runnable sender = new Runnable() { public void run() { + + Deflater deflater = new Deflater(); + Inflater inflater = new Inflater(); try { /** * initial connection of RFB protocol @@ -541,18 +533,37 @@ for (;;) { byte[] b = c.poll(); - os.write(b, 0, b.length); + 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 len = deflater.deflate(c); + byte[] blen = castIntByte(len); + os.write(b,0,20); + os.write(blen,0,4); + os.write(c,0,len); + } + } else + os.write(b, 0, b.length); } } catch (IOException e) { /** * if socket closed */ // cliList.remove(newCli); + } catch (DataFormatException e) { + // should print some error } } }; + clients++; new Thread(sender).start(); } diff -r 5970410efee7 -r 712a047908df src/myVncProxy/ProxyVncCanvas.java --- a/src/myVncProxy/ProxyVncCanvas.java Fri Jul 29 19:17:31 2011 +0900 +++ b/src/myVncProxy/ProxyVncCanvas.java Wed Aug 03 02:42:56 2011 +0900 @@ -371,7 +371,7 @@ */ rfb.sendDataToClient(); - int bufSize = (int)rfb.getNumBytesRead(); + long numBytesRead = rfb.getNumBytesRead(); // Read message type from the server. int msgType = rfb.readServerMessageType(); @@ -529,7 +529,7 @@ throw new Exception("Unknown RFB message type " + msgType); } - bufSize = (int)rfb.getNumBytesRead() - bufSize; + int bufSize = (int)(rfb.getNumBytesRead() - numBytesRead); // System.out.println("bufSize="+bufSize); // rfb.bufResetSend(bufSize); diff -r 5970410efee7 -r 712a047908df src/myVncProxy/VncCanvas.java --- a/src/myVncProxy/VncCanvas.java Fri Jul 29 19:17:31 2011 +0900 +++ b/src/myVncProxy/VncCanvas.java Wed Aug 03 02:42:56 2011 +0900 @@ -740,6 +740,7 @@ // These colors should be kept between handleHextileSubrect() calls. private Color hextile_bg, hextile_fg; + boolean noZRLEdecode = false; void handleHextileRect(int x, int y, int w, int h) throws IOException { @@ -887,7 +888,7 @@ // void handleZRLERect(int x, int y, int w, int h) throws Exception { - + if (noZRLEdecode) return; if (zrleInStream == null) zrleInStream = new ZlibInStream(); // System.out.println("zrleInStream.end="+zrleInStream.inflater.off); diff -r 5970410efee7 -r 712a047908df src/myVncProxy/VncProxyService.java --- a/src/myVncProxy/VncProxyService.java Fri Jul 29 19:17:31 2011 +0900 +++ b/src/myVncProxy/VncProxyService.java Wed Aug 03 02:42:56 2011 +0900 @@ -106,7 +106,7 @@ }catch(Exception e){} rfbThread = new Thread(this); - accThread = new Thread(new AcceptThread(rfb)); + accThread = new Thread(new AcceptThread(rfb, 5999)); } @@ -353,7 +353,7 @@ int[] encodings = new int[20]; int nEncodings = 0; -/* + encodings[nEncodings++] = preferredEncoding; if (options.useCopyRect) { encodings[nEncodings++] = RfbProto.EncodingCopyRect; @@ -367,11 +367,10 @@ if (preferredEncoding != RfbProto.EncodingHextile) { encodings[nEncodings++] = RfbProto.EncodingHextile; } -*/ if (preferredEncoding != RfbProto.EncodingZlib) { encodings[nEncodings++] = RfbProto.EncodingZlib; } -/* + /* if (preferredEncoding != RfbProto.EncodingCoRRE) { encodings[nEncodings++] = RfbProto.EncodingCoRRE; }