# HG changeset patch # User Shinji KONO # Date 1401096618 -32400 # Node ID 38e461e9b9c915462409ba0a7907d32be5c867b0 # Parent 92ceb7b1fe123b6b91017948ebf5f024efb16e27 remove duplicated code in MyRfbProto* diff -r 92ceb7b1fe12 -r 38e461e9b9c9 src/main/java/jp/ac/u_ryukyu/treevnc/MyRfbProto.java --- a/src/main/java/jp/ac/u_ryukyu/treevnc/MyRfbProto.java Mon May 26 13:57:03 2014 +0900 +++ b/src/main/java/jp/ac/u_ryukyu/treevnc/MyRfbProto.java Mon May 26 18:30:18 2014 +0900 @@ -1,11 +1,17 @@ package jp.ac.u_ryukyu.treevnc; import java.io.IOException; +import java.io.OutputStream; +import java.net.BindException; +import java.net.ServerSocket; import java.net.Socket; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.LinkedList; import java.util.concurrent.atomic.AtomicInteger; +import java.util.zip.DataFormatException; +import java.util.zip.Deflater; +import java.util.zip.Inflater; import jp.ac.u_ryukyu.treevnc.client.EchoClient; import jp.ac.u_ryukyu.treevnc.server.RequestScreenThread; @@ -32,11 +38,18 @@ private boolean proxyFlag = true; private EchoClient echo; private String proxyAddr; - public int acceptPort; + public int acceptPort = 0; protected boolean readyReconnect = false; private boolean cuiVersion; private long counter = 0; // packet serial number private VncProxyService viewer = null; + public ServerSocket servSock; + + private static final int INFLATE_BUFSIZE = 1024 * 100; + + private Inflater inflater = new Inflater(); + private Deflater deflater = new Deflater(); + public MyRfbProto() { @@ -237,7 +250,6 @@ } private void sendRfbVersion(Writer writer) throws IOException, TransportException { - // os.write(versionMsg_3_8.getBytes()); writer.write(versionMsg_3_856.getBytes()); } @@ -280,19 +292,10 @@ } private void sendPortNumber(Writer writer) throws TransportException { - byte[] b = new byte[4]; - //b = castIntByte(getHost.getPort()); - b = castIntByte(9999); - writer.write(b); - } - - private byte[] castIntByte(int len) { - byte[] b = new byte[4]; - b[0] = (byte) ((len >>> 24) & 0xFF); - b[1] = (byte) ((len >>> 16) & 0xFF); - b[2] = (byte) ((len >>> 8) & 0xFF); - b[3] = (byte) ((len >>> 0) & 0xFF); - return b; + ByteBuffer b = ByteBuffer.allocate(4); + b.order(ByteOrder.BIG_ENDIAN); + b.putInt(9999); + writer.write(b.array()); } @@ -315,8 +318,10 @@ } private void sendSecResult(Writer os) throws TransportException { - byte[] b = castIntByte(0); - os.write(b); + ByteBuffer b = ByteBuffer.allocate(4); + b.order(ByteOrder.BIG_ENDIAN); + b.putInt(0); + os.write(b.array()); } private void readClientInit(Reader in) throws TransportException { @@ -340,17 +345,32 @@ } - public void readSendData(int dataLen, Reader reader) throws TransportException { - - } - public Socket accept() throws IOException { return null; } - public int selectPort(int port) { - return port; - } + public void initServSock(int port) throws IOException { + servSock = new ServerSocket(port); + acceptPort = port; + } + + public int selectPort(int p) { + int port = p; + while (true) { + try { + initServSock(port); + break; + } catch (BindException e) { + port++; + continue; + } catch (IOException e) { + + } + } + System.out.println("accept port = " + port); + return port; + } + public void writeFramebufferUpdateRequest(int x, int y, int w, int h, @@ -404,13 +424,21 @@ this.proxyAddr = proxyAddr; } + void sendProxyFlag(OutputStream os) throws IOException { + if (proxyFlag) + os.write(1); + else + os.write(0); + } + + public void close() { // none } public int getAcceptPort() { - return 0; + return acceptPort; } public boolean getReadyReconnect() { @@ -473,10 +501,180 @@ public void stopReceiverTask() { if (context!=null) context.cleanUpSession(null); + // cleanup zlib decoder for new VNCServer + if (isRoot()) + inflater = new Inflater(); } public String getMyAddress() { return echo.getMyAddress(); } - + + /** + * gzip byte arrays + * + * @param deflater + * @param inputs + * byte data[] + * @param inputIndex + * @param outputs + * byte data[] + * @return byte length in last byte array + * @throws IOException + */ + public int zip(Deflater deflater, LinkedList inputs, + int inputIndex, LinkedList outputs) throws IOException { + int len = 0; + ByteBuffer c1 = multicastqueue.allocate(INFLATE_BUFSIZE); + while (inputIndex < inputs.size()) { + ByteBuffer b1 = inputs.get(inputIndex++); + deflater.setInput(b1.array(), b1.position(), b1.remaining()); + /** + * If we finish() stream and reset() it, Deflater start new gzip + * stream, this makes continuous zlib reader unhappy. if we remove + * finish(), Deflater.deflate() never flushes its output. The + * original zlib deflate has flush flag. I'm pretty sure this a kind + * of bug of Java library. + */ + if (inputIndex == inputs.size()) + deflater.finish(); + int len1 = 0; + do { + len1 = deflater.deflate(c1.array(), c1.position(), + c1.remaining()); + if (len1 > 0) { + len += len1; + c1.position(c1.position() + len1); + if (c1.remaining() == 0) { + c1.flip(); + outputs.addLast(c1); + c1 = multicastqueue.allocate(INFLATE_BUFSIZE); + } + } + } while (len1 > 0 || !deflater.needsInput()); // &&!deflater.finished()); + } + if (c1.position() != 0) { + c1.flip(); + outputs.addLast(c1); + } + deflater.reset(); + return len; + } + + /** + * gunzip byte arrays + * + * @param inflater + * @param inputs + * byte data[] + * @param outputs + * byte data[] + * @return number of total bytes + * @throws IOException + */ + public int unzip(Inflater inflater, LinkedList inputs, + int inputIndex, LinkedList outputs, int bufSize) + throws DataFormatException { + int len = 0; + ByteBuffer buf = multicastqueue.allocate(bufSize); + while (inputIndex < inputs.size()) { + ByteBuffer input = inputs.get(inputIndex++); + inflater.setInput(input.array(), input.position(), input.limit()); + // if (inputIndex==inputs.size()) if inflater/deflater has symmetry, + // we need this + // inflater.end(); but this won't work + do { + int len0 = inflater.inflate(buf.array(), buf.position(), + buf.remaining()); + if (len0 > 0) { + buf.position(buf.position() + len0); + len += len0; + if (buf.remaining() == 0) { + buf.flip(); + outputs.addLast(buf); + buf = multicastqueue.allocate(bufSize); + } + } + } while (!inflater.needsInput()); + } + if (buf.position() != 0) { + buf.flip(); + outputs.addLast(buf); + } + return len; + } + + public void readSendData(int dataLen, Reader reader) + throws TransportException { + LinkedList bufs = new LinkedList(); + ByteBuffer header = multicastqueue.allocate(16); + ByteBuffer serial = multicastqueue.allocate(8); + if (!isRoot()) { + reader.mark(dataLen+8); // +8 is serialnum + reader.readBytes(serial.array(),0,8); + serial.limit(8); + } + reader.readBytes(header.array(), 0, 16); + header.limit(16); + if (header.get(0) == FramebufferUpdate) { + int encoding = header.getInt(12); + if (encoding == EncodingType.ZRLE.getId() + || encoding == EncodingType.ZLIB.getId()) { // ZRLEE is + // already + // recompressed + ByteBuffer len = multicastqueue.allocate(4); + reader.readBytes(len.array(), 0, 4); + len.limit(4); + ByteBuffer inputData = multicastqueue.allocate(dataLen - 20); + reader.readBytes(inputData.array(), 0, inputData.capacity()); + inputData.limit(dataLen - 20); + LinkedList inputs = new LinkedList(); + inputs.add(inputData); + + header.putInt(12, EncodingType.ZRLEE.getId()); // means + // recompress + // every time + // using new Deflecter every time is incompatible with the + // protocol, clients have to be modified. + Deflater nDeflater = deflater; // new Deflater(); + LinkedList out = new LinkedList(); + try { + unzip(inflater, inputs, 0, out, INFLATE_BUFSIZE); + // dump32(inputs); + int len2 = zip(nDeflater, out, 0, bufs); + ByteBuffer blen = multicastqueue.allocate(4); + blen.putInt(len2); + blen.flip(); + bufs.addFirst(blen); + bufs.addFirst(header); + multicastqueue.put(bufs); + if (!isRoot()) reader.reset(); + } catch (DataFormatException e) { + throw new TransportException(e); + } catch (IOException e) { + throw new TransportException(e); + } + return; + } + if (!isRoot()) + bufs.add(serial); + bufs.add(header); + if (dataLen > 16) { + ByteBuffer b = multicastqueue.allocate(dataLen - 16); + reader.readBytes(b.array(), 0, dataLen - 16); + b.limit(dataLen - 16); + bufs.add(b); + } + multicastqueue.put(bufs); + return; + } + if (isRoot()) + reader.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. + } } diff -r 92ceb7b1fe12 -r 38e461e9b9c9 src/main/java/jp/ac/u_ryukyu/treevnc/client/MyRfbProtoClient.java --- a/src/main/java/jp/ac/u_ryukyu/treevnc/client/MyRfbProtoClient.java Mon May 26 13:57:03 2014 +0900 +++ b/src/main/java/jp/ac/u_ryukyu/treevnc/client/MyRfbProtoClient.java Mon May 26 18:30:18 2014 +0900 @@ -4,31 +4,22 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; -import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; -import java.net.BindException; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; import java.nio.ByteBuffer; import java.util.LinkedList; -import java.util.zip.DataFormatException; -import java.util.zip.Deflater; -import java.util.zip.Inflater; import jp.ac.u_ryukyu.treevnc.MyRfbProto; import com.glavsoft.exceptions.TransportException; -import com.glavsoft.rfb.encoding.EncodingType; import com.glavsoft.rfb.protocol.ProtocolContext; import com.glavsoft.transport.Reader; public class MyRfbProtoClient extends MyRfbProto { - private static final int INFLATE_BUFSIZE = 1024 * 100; private Reader reader; - private String host; - private int port; Socket clientSocket, sock; DataInputStream is; OutputStream os; @@ -39,8 +30,6 @@ int clientMajor, clientMinor; private boolean normalTermination; - private Inflater inflater = new Inflater(); - private Deflater deflater = new Deflater(); public MyRfbProtoClient() { @@ -70,309 +59,16 @@ } - int castByteInt(byte[] b) { - ByteBuffer bb = ByteBuffer.wrap(b); - int value = bb.getInt(); - return value; - } - @Override public Socket accept() throws IOException { servSock.setReuseAddress(true); return servSock.accept(); } - void initServSock(int port) throws IOException { - servSock = new ServerSocket(port); -// acceptPort = port; - } - - @Override - public int selectPort(int p) { - int port = p; - while (true) { - try { -// Thread.sleep(1000); - initServSock(port); - break; - } catch (BindException e) { - port++; - continue; - } catch (IOException e) { - - } - } - System.out.println("accept port = " + port); - return port; - } - - void sendRfbVersion(OutputStream os) throws IOException { - os.write(versionMsg_3_856.getBytes()); - } - - int readVersionMsg(InputStream is, OutputStream os) throws IOException { - - byte[] b = new byte[12]; - - is.read(b); - - if ((b[0] != 'R') || (b[1] != 'F') || (b[2] != 'B') || (b[3] != ' ') - || (b[4] < '0') || (b[4] > '9') || (b[5] < '0') || (b[5] > '9') - || (b[6] < '0') || (b[6] > '9') || (b[7] != '.') - || (b[8] < '0') || (b[8] > '9') || (b[9] < '0') || (b[9] > '9') - || (b[10] < '0') || (b[10] > '9') || (b[11] != '\n')) { - throw new IOException("Host " + host + " port " + port - + " is not an RFB server"); - } - - int rfbMajor = (b[4] - '0') * 100 + (b[5] - '0') * 10 + (b[6] - '0'); - int rfbMinor = (b[8] - '0') * 100 + (b[9] - '0') * 10 + (b[10] - '0'); - - if (rfbMajor < 3) { - throw new IOException( - "RFB server does not support protocol version 3"); - } - - if (rfbMinor == 855) { - sendProxyFlag(os); - // if(proxyFlag)sendPortNumber(os); - } - return rfbMinor; - - } - - void readVersionMsg(InputStream is) throws IOException { - - byte[] b = new byte[12]; - - is.read(b); - - if ((b[0] != 'R') || (b[1] != 'F') || (b[2] != 'B') || (b[3] != ' ') - || (b[4] < '0') || (b[4] > '9') || (b[5] < '0') || (b[5] > '9') - || (b[6] < '0') || (b[6] > '9') || (b[7] != '.') - || (b[8] < '0') || (b[8] > '9') || (b[9] < '0') || (b[9] > '9') - || (b[10] < '0') || (b[10] > '9') || (b[11] != '\n')) { - throw new IOException("Host " + host + " port " + port - + " is not an RFB server"); - } - - serverMajor = (b[4] - '0') * 100 + (b[5] - '0') * 10 + (b[6] - '0'); - serverMinor = (b[8] - '0') * 100 + (b[9] - '0') * 10 + (b[10] - '0'); - - if (serverMajor < 3) { - throw new IOException( - "RFB server does not support protocol version 3"); - } - - } - - void sendSecurityType(OutputStream os) throws IOException { - // number-of-security-types - os.write(1); - // security-types - // 1:None - os.write(1); - } - - void readSecType(InputStream is) throws IOException { - byte[] b = new byte[1]; - is.read(b); - - } - - void sendSecResult(OutputStream os) throws IOException { - byte[] b = castIntByte(0); - os.write(b); - } - - void readClientInit(InputStream in) throws IOException { - byte[] b = new byte[0]; - in.read(b); - } - void sendInitData(OutputStream os) throws IOException { os.write(context.getInitData()); } - void sendProxyFlag(OutputStream os) throws IOException { - if (proxyFlag) - os.write(1); - else - os.write(0); - } - - byte[] castIntByte(int len) { - byte[] b = new byte[4]; - b[0] = (byte) ((len >>> 24) & 0xFF); - b[1] = (byte) ((len >>> 16) & 0xFF); - b[2] = (byte) ((len >>> 8) & 0xFF); - b[3] = (byte) ((len >>> 0) & 0xFF); - return b; - } - - /** - * gzip byte arrays - * - * @param deflater - * @param inputs - * byte data[] - * @param inputIndex - * @param outputs - * byte data[] - * @return byte length in last byte array - * @throws IOException - */ - public int zip(Deflater deflater, LinkedList inputs, - int inputIndex, LinkedList outputs) throws IOException { - int len = 0; - ByteBuffer c1 = multicastqueue.allocate(INFLATE_BUFSIZE); - while (inputIndex < inputs.size()) { - ByteBuffer b1 = inputs.get(inputIndex++); - deflater.setInput(b1.array(), b1.position(), b1.remaining()); - /** - * If we finish() stream and reset() it, Deflater start new gzip - * stream, this makes continuous zlib reader unhappy. if we remove - * finish(), Deflater.deflate() never flushes its output. The - * original zlib deflate has flush flag. I'm pretty sure this a kind - * of bug of Java library. - */ - if (inputIndex == inputs.size()) - deflater.finish(); - int len1 = 0; - do { - len1 = deflater.deflate(c1.array(), c1.position(), - c1.remaining()); - if (len1 > 0) { - len += len1; - c1.position(c1.position() + len1); - if (c1.remaining() == 0) { - c1.flip(); - outputs.addLast(c1); - c1 = multicastqueue.allocate(INFLATE_BUFSIZE); - } - } - } while (len1 > 0 || !deflater.needsInput()); // &&!deflater.finished()); - } - if (c1.position() != 0) { - c1.flip(); - outputs.addLast(c1); - } - deflater.reset(); - return len; - } - - /** - * gunzip byte arrays - * - * @param inflater - * @param inputs - * byte data[] - * @param outputs - * byte data[] - * @return number of total bytes - * @throws IOException - */ - public int unzip(Inflater inflater, LinkedList inputs, - int inputIndex, LinkedList outputs, int bufSize) - throws DataFormatException { - int len = 0; - ByteBuffer buf = multicastqueue.allocate(bufSize); - while (inputIndex < inputs.size()) { - ByteBuffer input = inputs.get(inputIndex++); - inflater.setInput(input.array(), input.position(), input.limit()); - // if (inputIndex==inputs.size()) if inflater/deflater has symmetry, - // we need this - // inflater.end(); but this won't work - do { - int len0 = inflater.inflate(buf.array(), buf.position(), - buf.remaining()); - if (len0 > 0) { - buf.position(buf.position() + len0); - len += len0; - if (buf.remaining() == 0) { - buf.flip(); - outputs.addLast(buf); - buf = multicastqueue.allocate(bufSize); - } - } - } while (!inflater.needsInput()); - } - if (buf.position() != 0) { - buf.flip(); - outputs.addLast(buf); - } - return len; - } - - public void readSendData(int dataLen, Reader reader) - throws TransportException { - LinkedList bufs = new LinkedList(); - ByteBuffer header = multicastqueue.allocate(16); - ByteBuffer serial = multicastqueue.allocate(8); - reader.mark(dataLen+8); // +8 is serialnum - reader.readBytes(serial.array(),0,8); - serial.limit(8); - reader.readBytes(header.array(), 0, 16); - header.limit(16); - if (header.get(0) == FramebufferUpdate) { - int encoding = header.getInt(12); - if (encoding == EncodingType.ZRLE.getId() - || encoding == EncodingType.ZLIB.getId()) { // ZRLEE is - // already - // recompressed - ByteBuffer len = multicastqueue.allocate(4); - reader.readBytes(len.array(), 0, 4); - len.limit(4); - ByteBuffer inputData = multicastqueue.allocate(dataLen - 20); - reader.readBytes(inputData.array(), 0, inputData.capacity()); - inputData.limit(dataLen - 20); - LinkedList inputs = new LinkedList(); - inputs.add(inputData); - - header.putInt(12, EncodingType.ZRLEE.getId()); // means - // recompress - // every time - // using new Deflecter every time is incompatible with the - // protocol, clients have to be modified. - Deflater nDeflater = deflater; // new Deflater(); - LinkedList out = new LinkedList(); - try { - unzip(inflater, inputs, 0, out, INFLATE_BUFSIZE); - // dump32(inputs); - int len2 = zip(nDeflater, out, 0, bufs); - ByteBuffer blen = multicastqueue.allocate(4); - blen.putInt(len2); - blen.flip(); - bufs.addFirst(blen); - - bufs.addFirst(header); - multicastqueue.put(bufs); - reader.reset(); - } catch (DataFormatException e) { - throw new TransportException(e); - } catch (IOException e) { - throw new TransportException(e); - } - return; - } - } - bufs.add(serial); - bufs.add(header); - if (dataLen > 16) { - ByteBuffer b = multicastqueue.allocate(dataLen - 16); - reader.readBytes(b.array(), 0, dataLen - 16); - b.limit(dataLen - 16); - bufs.add(b); - } - multicastqueue.put(bufs); - reader.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. - } @Override public void setTerminationType(boolean setType) { diff -r 92ceb7b1fe12 -r 38e461e9b9c9 src/main/java/jp/ac/u_ryukyu/treevnc/server/CreateThread.java --- a/src/main/java/jp/ac/u_ryukyu/treevnc/server/CreateThread.java Mon May 26 13:57:03 2014 +0900 +++ b/src/main/java/jp/ac/u_ryukyu/treevnc/server/CreateThread.java Mon May 26 18:30:18 2014 +0900 @@ -18,19 +18,11 @@ acceptClient = _acc; port = 9999; } - - - public CreateThread(int port,AcceptClient _acc) { - acceptClient = _acc; - this.port = port; - } void newEchoClient(final BufferedReader is,final PrintStream os) { Runnable echoSender = new Runnable() { public void run() { - // AcceptClient acceptClient = new AcceptClient(); - // acceptClient new acceptClient.transferParentAddrerss(is,os); } }; diff -r 92ceb7b1fe12 -r 38e461e9b9c9 src/main/java/jp/ac/u_ryukyu/treevnc/server/MyRfbProtoProxy.java --- a/src/main/java/jp/ac/u_ryukyu/treevnc/server/MyRfbProtoProxy.java Mon May 26 13:57:03 2014 +0900 +++ b/src/main/java/jp/ac/u_ryukyu/treevnc/server/MyRfbProtoProxy.java Mon May 26 18:30:18 2014 +0900 @@ -4,21 +4,14 @@ //import org.junit.Test; import java.io.IOException; -import java.net.BindException; import java.net.ServerSocket; import java.net.Socket; import java.nio.ByteBuffer; import java.util.LinkedList; -import com.glavsoft.exceptions.TransportException; -import com.glavsoft.rfb.encoding.EncodingType; -import com.glavsoft.transport.Reader; import com.glavsoft.transport.Writer; import java.util.concurrent.ExecutorService; -import java.util.zip.DataFormatException; -import java.util.zip.Deflater; -import java.util.zip.Inflater; import jp.ac.u_ryukyu.treevnc.MyRfbProto; @@ -34,7 +27,6 @@ // Supported authentication types final static int AuthAccess = 32; - private static final int INFLATE_BUFSIZE = 1024 * 100; boolean printStatusFlag = false; long startCheckTime; @@ -48,16 +40,11 @@ byte[] pngBytes; - private Inflater inflater = new Inflater(); - private Deflater deflater = new Deflater(); - public RequestScreenThread rThread; private Thread requestThread; private int rangeX = 256; // screenRange XPosition private int rangeY = 256; // screenRange YPosition - // private int rangeWidth = 512; // screenRange Width private int rangeHeight = 256; // screenRange Height - public MyRfbProtoProxy() { rThread = new RequestScreenThread(this); @@ -73,33 +60,6 @@ // os = _writer; } - void initServSock(int port) throws IOException { - servSock = new ServerSocket(port); - acceptPort = port; - } - - /* - * default port number is 5999. - */ - public int selectPort(int p) { - if (servSock != null) - return 0; - int port = p; - while (true) { - try { - initServSock(port); - break; - } catch (BindException e) { - port++; - continue; - } catch (IOException e) { - - } - } - System.out.println("accept port = " + port); - return port; - } - public int getAcceptPort() { return acceptPort; } @@ -125,19 +85,6 @@ cliListTmp.add(sock); } - synchronized void changeStatusFlag() { - printStatusFlag = true; - } - - void printMills() { - if (printStatusFlag) { - - changeStatusFlag(); - } else { - changeStatusFlag(); - } - } - void requestThreadStart() { requestThread.start(); } @@ -146,198 +93,6 @@ rThread.reStart(); } - /** - * gzip byte arrays - * - * @param deflater - * @param inputs - * byte data[] - * @param inputIndex - * @param outputs - * byte data[] - * @return byte length in last byte array - * @throws IOException - */ - public int zip(Deflater deflater, LinkedList inputs, - int inputIndex, LinkedList outputs) throws IOException { - int len = 0; - ByteBuffer c1 = multicastqueue.allocate(INFLATE_BUFSIZE); - while (inputIndex < inputs.size()) { - ByteBuffer b1 = inputs.get(inputIndex++); - deflater.setInput(b1.array(), b1.position(), b1.remaining()); - /** - * If we finish() stream and reset() it, Deflater start new gzip - * stream, this makes continuous zlib reader unhappy. if we remove - * finish(), Deflater.deflate() never flushes its output. The - * original zlib deflate has flush flag. I'm pretty sure this a kind - * of bug of Java library. - */ - if (inputIndex == inputs.size()) - deflater.finish(); - int len1 = 0; - do { - len1 = deflater.deflate(c1.array(), c1.position(), - c1.remaining()); - if (len1 > 0) { - len += len1; - c1.position(c1.position() + len1); - if (c1.remaining() == 0) { - c1.flip(); - outputs.addLast(c1); - c1 = multicastqueue.allocate(INFLATE_BUFSIZE); - } - } - } while (len1 > 0 || !deflater.needsInput()); // &&!deflater.finished()); - } - if (c1.position() != 0) { - c1.flip(); - outputs.addLast(c1); - } - deflater.reset(); - return len; - } - - /** - * gunzip byte arrays - * - * @param inflater - * @param inputs - * byte data[] - * @param outputs - * byte data[] - * @return number of total bytes - * @throws IOException - */ - public int unzip(Inflater inflater, LinkedList inputs, - int inputIndex, LinkedList outputs, int bufSize) - throws DataFormatException { - int len = 0; - ByteBuffer buf = multicastqueue.allocate(bufSize); - while (inputIndex < inputs.size()) { - ByteBuffer input = inputs.get(inputIndex++); - inflater.setInput(input.array(), input.position(), input.limit()); - // if (inputIndex==inputs.size()) if inflater/deflater has symmetry, - // we need this - // inflater.end(); but this won't work - do { - int len0 = inflater.inflate(buf.array(), buf.position(), - buf.remaining()); - if (len0 > 0) { - buf.position(buf.position() + len0); - len += len0; - if (buf.remaining() == 0) { - buf.flip(); - outputs.addLast(buf); - buf = multicastqueue.allocate(bufSize); - } - } - } while (!inflater.needsInput()); - } - if (buf.position() != 0) { - buf.flip(); - outputs.addLast(buf); - } - return len; - } - - float maxMag = 1; - - /** - * send data to clients - * - * @param dataLen - * @param is - * @throws IOException - * @throws DataFormatException - * - * Zlibed packet is compressed in context dependent way, that - * is, it have to send from the beginning. But this is - * impossible. So we have to compress it again for each clients. - * Separate deflater for each clients is necessary. - * - * Java's deflater does not support flush. This means to get the - * result, we have to finish the compression. Reseting start new - * compression, but it is not accepted well in zlib continuous - * reading. So we need new Encoding ZRLEE which reset decoder - * for each packet. ZRLEE can be invisible from user, but it - * have to be implemented in the clients. ZRLEE compression is - * not context dependent, so no recompression is necessary. - * @throws TransportException - */ - public void readSendData(int dataLen, Reader is) throws TransportException { - LinkedList bufs = new LinkedList(); - ByteBuffer header = multicastqueue.allocate(16); - is.readBytes(header.array(), 0, 16); - header.limit(16); - if (header.get(0) == FramebufferUpdate) { - int encoding = header.getInt(12); - if (encoding == EncodingType.ZRLE.getId() - || encoding == EncodingType.ZLIB.getId()) { // ZRLEE is - // already - // recompressed - ByteBuffer len = multicastqueue.allocate(4); - is.readBytes(len.array(), 0, 4); - len.limit(4); - ByteBuffer inputData = multicastqueue.allocate(dataLen - 20); - - is.readBytes(inputData.array(), 0, inputData.capacity()); - // System.out.println(dataLen); - inputData.limit(dataLen - 20); - - LinkedList inputs = new LinkedList(); - inputs.add(inputData); - - header.putInt(12, EncodingType.ZRLEE.getId()); // means - // recompress - // every time - // using new Deflecter every time is incompatible with the - // protocol, clients have to be modified. - Deflater nDeflater = deflater; // new Deflater(); - LinkedList out = new LinkedList(); - //List out = java.util.Collections.synchronizedList(new LinkedList()); - int len2 = 0; - try { - unzip(inflater, inputs, 0, out, INFLATE_BUFSIZE); - len2 = zip(nDeflater, out, 0, bufs); - out = null; - multicastqueue.heapAvailable(); - } catch (DataFormatException e) { - throw new TransportException(e); - } catch (IOException e) { - throw new TransportException(e); - } - - ByteBuffer blen = multicastqueue.allocate(4); - blen.putInt(len2); - blen.flip(); - bufs.addFirst(blen); - bufs.addFirst(header); - addSerialNumber(bufs); - multicastqueue.put(bufs); - - return; - } - bufs.add(header); - if (dataLen > 16) { - ByteBuffer b = multicastqueue.allocate(dataLen - 16); - is.readBytes(b.array(), 0, dataLen - 16); - b.limit(dataLen - 16); - bufs.add(b); - } - multicastqueue.put(bufs); - // is.reset(); - return; - } - 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. - } - public void dump32(LinkedList bufs) { int len = 0; for (ByteBuffer b : bufs) @@ -356,133 +111,8 @@ System.err.println(); } - /* - * @Test public void test1() { try { LinkedList in = new - * LinkedList(); LinkedList out = new - * LinkedList(); LinkedList out2 = new - * LinkedList(); // if (false) { // for(int i=0;i<10;i++) { // - * in.add(ByteBuffer.wrap("test1".getBytes())); // - * in.add(ByteBuffer.wrap("test2".getBytes())); // - * in.add(ByteBuffer.wrap("test3".getBytes())); // - * in.add(ByteBuffer.wrap("test44".getBytes())); // } // } else { String t = - * ""; for (int i = 0; i < 10; i++) { t += "test1"; t += "test2"; t += - * "test3"; t += "test44"; } in.add(ByteBuffer.wrap(t.getBytes())); } - * - * LinkedList in1 = clone(in); - * - * Deflater deflater = new Deflater(); zip(deflater, in, 0, out); // - * LinkedList out3 = clone(out); zipped result is depend // on - * deflator's state unzip(inflater, out, 0, out2, INFLATE_BUFSIZE); // - * inflater.reset(); equalByteBuffers(in1, out2); LinkedList - * out4 = new LinkedList(); deflater = new Deflater(); - * zip(deflater, out2, 0, out4); LinkedList out5 = new - * LinkedList(); unzip(inflater, out4, 0, out5, - * INFLATE_BUFSIZE); int len = equalByteBuffers(in1, out5); - * - * System.out.println("Test Ok. " + len); } catch (Exception e) { - * assertEquals(0, 1); } } - */ - - /* - * public int equalByteBuffers(LinkedList in, - * LinkedList out2) { int len = 0; Iterable i = - * byteBufferIterator(in); Iterator o = - * byteBufferIterator(out2).iterator(); - * - * for (int b : i) { len++; if (o.hasNext()) { int c = o.next(); - * assertEquals(b, c); } else assertEquals(0, 1); } if (o.hasNext()) - * assertEquals(0, 1); // System.out.println(); return len; } - */ - - void sendRfbVersion(Writer writer) throws IOException, TransportException { - // os.write(versionMsg_3_8.getBytes()); - writer.write(versionMsg_3_856.getBytes()); - } - - int readVersionMsg(Reader reader, Writer writer) throws IOException, - TransportException { - - byte[] b = new byte[12]; - - reader.readBytes(b); - - if ((b[0] != 'R') || (b[1] != 'F') || (b[2] != 'B') || (b[3] != ' ') - || (b[4] < '0') || (b[4] > '9') || (b[5] < '0') || (b[5] > '9') - || (b[6] < '0') || (b[6] > '9') || (b[7] != '.') - || (b[8] < '0') || (b[8] > '9') || (b[9] < '0') || (b[9] > '9') - || (b[10] < '0') || (b[10] > '9') || (b[11] != '\n')) { - throw new IOException("this is not an RFB server"); - } - - int rfbMajor = (b[4] - '0') * 100 + (b[5] - '0') * 10 + (b[6] - '0'); - int rfbMinor = (b[8] - '0') * 100 + (b[9] - '0') * 10 + (b[10] - '0'); - if (rfbMajor < 3) { - throw new IOException( - "RFB server does not support protocol version 3"); - } - if (rfbMinor == 855) { - sendProxyFlag(writer); - if (proxyFlag) - sendPortNumber(writer); - } - return rfbMinor; - } - - void sendProxyFlag(Writer writer) throws TransportException { - if (proxyFlag) - writer.writeInt(1); - else - writer.writeInt(0); - } - - void sendPortNumber(Writer writer) throws TransportException { - byte[] b = new byte[4]; - // b = castIntByte(getHost.getPort()); - b = castIntByte(9999); - writer.write(b); - } - - void sendSecurityType(Writer os) throws TransportException { - // number-of-security-types - os.writeInt(1); - // security-types - // 1:None - os.writeInt(1); - - /* - * os.write(4); os.write(30); os.write(31); os.write(32); os.write(35); - * os.flush(); - */ - } - - void readSecType(Reader reader) throws TransportException { - byte[] b = new byte[1]; - reader.read(b); - } - - - - void sendSecResult(Writer os) throws TransportException { - byte[] b = castIntByte(0); - os.write(b); - } - - byte[] castIntByte(int len) { - byte[] b = new byte[4]; - b[0] = (byte) ((len >>> 24) & 0xFF); - b[1] = (byte) ((len >>> 16) & 0xFF); - b[2] = (byte) ((len >>> 8) & 0xFF); - b[3] = (byte) ((len >>> 0) & 0xFF); - return b; - } - - void readClientInit(Reader in) throws TransportException { - byte[] b = new byte[0]; - in.readBytes(b); - } - @Override public boolean getReadyReconnect() { return readyReconnect; @@ -533,10 +163,5 @@ } - @Override - public void stopReceiverTask() { - super.stopReceiverTask(); - inflater = new Inflater(); - } } diff -r 92ceb7b1fe12 -r 38e461e9b9c9 src/main/java/jp/ac/u_ryukyu/treevnc/server/VncProxyService.java --- a/src/main/java/jp/ac/u_ryukyu/treevnc/server/VncProxyService.java Mon May 26 13:57:03 2014 +0900 +++ b/src/main/java/jp/ac/u_ryukyu/treevnc/server/VncProxyService.java Mon May 26 18:30:18 2014 +0900 @@ -157,8 +157,6 @@ CreateThread createThread = new CreateThread(clients); Thread thread = new Thread(createThread); thread.start(); - // Thread thread2 = new Thread(new ChangeHost(this, forceReconnection)); - // thread2.start(); } protected void socketClose() {