Mercurial > hg > Applications > TreeVNC
diff src/main/java/jp/ac/u_ryukyu/treevnc/TreeRFBProto.java @ 223:3189e210a7ed
indent fix.
author | oc |
---|---|
date | Sun, 06 Jul 2014 12:46:20 +0900 |
parents | b31903e5b02d |
children | b7247e31b5ba |
line wrap: on
line diff
--- a/src/main/java/jp/ac/u_ryukyu/treevnc/TreeRFBProto.java Sun Jul 06 10:36:30 2014 +0900 +++ b/src/main/java/jp/ac/u_ryukyu/treevnc/TreeRFBProto.java Sun Jul 06 12:46:20 2014 +0900 @@ -27,18 +27,18 @@ public class TreeRFBProto { - final static int FramebufferUpdateRequest = 3; - final static int CheckDelay = 11; - protected final static int FramebufferUpdate = 0; - protected ProtocolContext context; - private int clients = 0; - public MulticastQueue<LinkedList<ByteBuffer>> multicastqueue = new MulticastQueue<LinkedList<ByteBuffer>>(); - private RequestScreenThread rThread; - public int acceptPort = 0; + final static int FramebufferUpdateRequest = 3; + final static int CheckDelay = 11; + protected final static int FramebufferUpdate = 0; + protected ProtocolContext context; + private int clients = 0; + public MulticastQueue<LinkedList<ByteBuffer>> multicastqueue = new MulticastQueue<LinkedList<ByteBuffer>>(); + private RequestScreenThread rThread; + public int acceptPort = 0; private String myAddress; - protected boolean readyReconnect = false; - private boolean cuiVersion; - private long counter = 0; // packet serial number + protected boolean readyReconnect = false; + private boolean cuiVersion; + private long counter = 0; // packet serial number public ServerSocket servSock; private boolean permitChangeScreen = true; private static final int INFLATE_BUFSIZE = 1024 * 100; @@ -46,228 +46,228 @@ private Inflater inflater = new Inflater(); private Deflater deflater = new Deflater(); ViewerInterface viewer; - private short id; // my tree node id ( = 0 in root ) + private short id; // my tree node id ( = 0 in root ) private boolean leader; private TreeVncCommandChannelListener acceptThread; private boolean firstTime = true; private TreeRootFinderListener getCast; private CreateConnectionParam cp; private boolean hasViewer = false; - public boolean showTreeNode = false; + public boolean showTreeNode = false; private boolean reconnecting; private short reconnectingId; // Change Server Request to id's node VNC server private TreeVNCNetwork nets = new TreeVNCNetwork(); - private boolean normalTermination; - private TreeVncRootSelectionPanel rootSelectionPanel; - private boolean isTreeManager; - private String vncInterface; + private boolean normalTermination; + private TreeVncRootSelectionPanel rootSelectionPanel; + private boolean isTreeManager; + private String vncInterface; + + public TreeRFBProto(boolean isTreeManager) { + rThread = new RequestScreenThread(this); + nets.setMyRfb(this); + this.isTreeManager = isTreeManager; + } + + public boolean isTreeManager() { + return isTreeManager; + } - public TreeRFBProto(boolean isTreeManager) { - rThread = new RequestScreenThread(this); - nets.setMyRfb(this); - this.isTreeManager = isTreeManager; - } - - public boolean isTreeManager() { - return isTreeManager; - } - - public ProtocolContext getContext() { - return context; - } - - /** - * handle new client accept - * it also handle TreeVNC Command - * @param acceptThread - * @param newCli - * @param os - * @param is - * @throws IOException - * @throws TransportException - */ - public void newClient(final Socket newCli,final Writer os, final Reader is) { + public ProtocolContext getContext() { + return context; + } + + /** + * handle new client accept + * it also handle TreeVNC Command + * @param acceptThread + * @param newCli + * @param os + * @param is + * @throws IOException + * @throws TransportException + */ + public void newClient(final Socket newCli,final Writer os, final Reader is) { - final int myId = clients; - final MulticastQueue.Client<LinkedList<ByteBuffer>> c = multicastqueue.newClient(); - final AtomicInteger writerRunning = new AtomicInteger(); - writerRunning.set(1); - /** - * Timeout thread. If a client is suspended, it has top of queue - * indefinitely, which caused memory overflow. After the timeout, we - * poll the queue and discard it. Start long wait if writer is running. - */ - final Runnable timer = new Runnable() { - public void run() { - int count = 0; - for (;;) { - long timeout = 50000 / 8; - try { - synchronized (this) { - int state, flag; - writerRunning.set(0); - wait(timeout); - flag = 0; - while ((state = writerRunning.get()) == 0) { - c.poll(); // discard, should be timeout - count++; - if (flag == 0) { - System.out.println("Discarding " + myId - + " count=" + count); - flag = 1; - } - wait(10); // if this is too short, writer cannot - // take the poll, if this is too - // long, memory will overflow... - } - if (flag == 1) - System.out.println("Resuming " + myId - + " count=" + count); - if (state != 1) { - System.out.println("Client died " + myId); - break; - } - } - } catch (InterruptedException e) { - } - } - } - }; - new Thread(timer, "timer-discard-multicastqueue").start(); - /** - * handle command from lower node - */ - final Runnable reader = new Runnable() { + final int myId = clients; + final MulticastQueue.Client<LinkedList<ByteBuffer>> c = multicastqueue.newClient(); + final AtomicInteger writerRunning = new AtomicInteger(); + writerRunning.set(1); + /** + * Timeout thread. If a client is suspended, it has top of queue + * indefinitely, which caused memory overflow. After the timeout, we + * poll the queue and discard it. Start long wait if writer is running. + */ + final Runnable timer = new Runnable() { + public void run() { + int count = 0; + for (;;) { + long timeout = 50000 / 8; + try { + synchronized (this) { + int state, flag; + writerRunning.set(0); + wait(timeout); + flag = 0; + while ((state = writerRunning.get()) == 0) { + c.poll(); // discard, should be timeout + count++; + if (flag == 0) { + System.out.println("Discarding " + myId + + " count=" + count); + flag = 1; + } + wait(10); // if this is too short, writer cannot + // take the poll, if this is too + // long, memory will overflow... + } + if (flag == 1) + System.out.println("Resuming " + myId + + " count=" + count); + if (state != 1) { + System.out.println("Client died " + myId); + break; + } + } + } catch (InterruptedException e) { + } + } + } + }; + new Thread(timer, "timer-discard-multicastqueue").start(); + /** + * handle command from lower node + */ + final Runnable reader = new Runnable() { public void run() { - for (;;) { - try { - final byte b[] = new byte[4096]; - final int c = is.readByte(b); - if (c <= 0) - throw new IOException(); - if (isTreeManager()) { - if (b[0] == ClientToServerMessage.SERVER_CHANGE_REQUEST) { - if (permitChangeScreen()) { - ByteBuffer buf = ByteBuffer.wrap(b); - buf.order(ByteOrder.BIG_ENDIAN); - short id = buf.getShort(2); - int length = buf.getInt(4); - if (length == 0) - continue; - String newHostName = new String(b, 8, length); - System.out.println("Root server change request :" + newHostName); - // please remove these numbers. - if (viewer != null) { - changeVNCServer(viewer, newHostName, 3200, 1980, id); - } - } else { - continue; - } - } - } else if (b[0] == ClientToServerMessage.SERVER_CHANGE_REQUEST) { - ClientToServerMessage sc = new ClientToServerMessage() { + for (;;) { + try { + final byte b[] = new byte[4096]; + final int c = is.readByte(b); + if (c <= 0) + throw new IOException(); + if (isTreeManager()) { + if (b[0] == ClientToServerMessage.SERVER_CHANGE_REQUEST) { + if (permitChangeScreen()) { + ByteBuffer buf = ByteBuffer.wrap(b); + buf.order(ByteOrder.BIG_ENDIAN); + short id = buf.getShort(2); + int length = buf.getInt(4); + if (length == 0) + continue; + String newHostName = new String(b, 8, length); + System.out.println("Root server change request :" + newHostName); + // please remove these numbers. + if (viewer != null) { + changeVNCServer(viewer, newHostName, 3200, 1980, id); + } + } else { + continue; + } + } + } else if (b[0] == ClientToServerMessage.SERVER_CHANGE_REQUEST) { + ClientToServerMessage sc = new ClientToServerMessage() { @Override public void send(Writer writer) throws TransportException { writer.write(b,0,c); } - }; - context.sendMessage(sc); - } - // System.out.println("client read "+c); - } catch (Exception e) { - try { - writerRunning.set(2); - os.close(); - is.close(); - break; - } catch (IOException e1) { - } catch (TransportException e1) { - e1.printStackTrace(); - } - return; - } - } - } + }; + context.sendMessage(sc); + } + // System.out.println("client read "+c); + } catch (Exception e) { + try { + writerRunning.set(2); + os.close(); + is.close(); + break; + } catch (IOException e1) { + } catch (TransportException e1) { + e1.printStackTrace(); + } + return; + } + } + } - }; - /** - * send packets to a client (one thread for each client ) - */ - Runnable sender = new Runnable() { - public void run() { - writerRunning.set(1); - try { - requestThreadNotify(); + }; + /** + * send packets to a client (one thread for each client ) + */ + Runnable sender = new Runnable() { + public void run() { + writerRunning.set(1); + try { + requestThreadNotify(); - // after this, we discard upward packet. - new Thread(reader, "upward-packet-processing").start(); + // after this, we discard upward packet. + new Thread(reader, "upward-packet-processing").start(); - for (;;) { - LinkedList<ByteBuffer> bufs = c.poll(); - int inputIndex = 0; - ByteBuffer header = bufs.get(inputIndex); - if (header == null) - continue; - else if (header.get(0) == CheckDelay) { - writeToClient(os, bufs, inputIndex); - continue; - } else if (header.get(0) == FramebufferUpdate) { - //System.out.println("client "+ myId); - } - /* - * if(i%20==0){ sendDataCheckDelay(); } i++; - */ - writeToClient(os, bufs, inputIndex); - writerRunning.set(1); // yes my client is awaking. - } - } catch (Exception e) { - try { - writerRunning.set(2); - os.close(); - } catch (IOException e1) { - System.out.println("root writer close faild :" + e1); - } - System.out.println("root writer faild :" + e); - /* if socket closed cliList.remove(newCli); */ - } - } + for (;;) { + LinkedList<ByteBuffer> bufs = c.poll(); + int inputIndex = 0; + ByteBuffer header = bufs.get(inputIndex); + if (header == null) + continue; + else if (header.get(0) == CheckDelay) { + writeToClient(os, bufs, inputIndex); + continue; + } else if (header.get(0) == FramebufferUpdate) { + //System.out.println("client "+ myId); + } + /* + * if(i%20==0){ sendDataCheckDelay(); } i++; + */ + writeToClient(os, bufs, inputIndex); + writerRunning.set(1); // yes my client is awaking. + } + } catch (Exception e) { + try { + writerRunning.set(2); + os.close(); + } catch (IOException e1) { + System.out.println("root writer close faild :" + e1); + } + System.out.println("root writer faild :" + e); + /* if socket closed cliList.remove(newCli); */ + } + } - public void writeToClient(final Writer os, - LinkedList<ByteBuffer> bufs, int inputIndex) - throws TransportException { - while (inputIndex < bufs.size()) { - ByteBuffer b = bufs.get(inputIndex++); - os.write(b.array(), b.position(), b.limit()); - } - os.flush(); - bufs = null; - multicastqueue.heapAvailable(); - } - }; - clients++; - new Thread(sender, "writer-to-lower-node").start(); + public void writeToClient(final Writer os, + LinkedList<ByteBuffer> bufs, int inputIndex) + throws TransportException { + while (inputIndex < bufs.size()) { + ByteBuffer b = bufs.get(inputIndex++); + os.write(b.array(), b.position(), b.limit()); + } + os.flush(); + bufs = null; + multicastqueue.heapAvailable(); + } + }; + clients++; + new Thread(sender, "writer-to-lower-node").start(); - } + } - + public boolean permitChangeScreen() { return permitChangeScreen; } - + public void setPermitChangeScreen(boolean v) { - permitChangeScreen = v; + permitChangeScreen = v; } - - public void requestThreadNotify() { - rThread.reStart(); - } - - + + public void requestThreadNotify() { + rThread.reStart(); + } + + public void setProtocolContext(Protocol workingProtocol) { context = workingProtocol; } @@ -298,131 +298,131 @@ - public void writeFramebufferUpdateRequest(int x, int y, int w, int h, - boolean incremental) throws TransportException { - byte[] b = new byte[10]; + public void writeFramebufferUpdateRequest(int x, int y, int w, int h, + boolean incremental) throws TransportException { + byte[] b = new byte[10]; + + b[0] = (byte) FramebufferUpdateRequest; // 3 is FrameBufferUpdateRequest + b[1] = (byte) (incremental ? 1 : 0); + b[2] = (byte) ((x >> 8) & 0xff); + b[3] = (byte) (x & 0xff); + b[4] = (byte) ((y >> 8) & 0xff); + b[5] = (byte) (y & 0xff); + b[6] = (byte) ((w >> 8) & 0xff); + b[7] = (byte) (w & 0xff); + b[8] = (byte) ((h >> 8) & 0xff); + b[9] = (byte) (h & 0xff); + } - b[0] = (byte) FramebufferUpdateRequest; // 3 is FrameBufferUpdateRequest - b[1] = (byte) (incremental ? 1 : 0); - b[2] = (byte) ((x >> 8) & 0xff); - b[3] = (byte) (x & 0xff); - b[4] = (byte) ((y >> 8) & 0xff); - b[5] = (byte) (y & 0xff); - b[6] = (byte) ((w >> 8) & 0xff); - b[7] = (byte) (w & 0xff); - b[8] = (byte) ((h >> 8) & 0xff); - b[9] = (byte) (h & 0xff); - } - - public void setViewer(ViewerInterface v) { - viewer = v; - } - - public ViewerInterface getViewer() { - return viewer; - } + public void setViewer(ViewerInterface v) { + viewer = v; + } + + public ViewerInterface getViewer() { + return viewer; + } + + + void sendInitData(OutputStream os) throws IOException { + os.write(context.getInitData()); + } + + + public void setTerminationType(boolean setType) { + normalTermination = setType; + } + + public boolean getTerminationType() { + return normalTermination; + } - void sendInitData(OutputStream os) throws IOException { - os.write(context.getInitData()); - } + public void addHostToSelectionPanel(int port, String hostname,String myHostName) { + if (rootSelectionPanel != null) { + rootSelectionPanel.checkBox(Integer.toString(port) + ":" + hostname + ":" + myHostName); + rootSelectionPanel.setButton(); + rootSelectionPanel.visible(); + } + } - - public void setTerminationType(boolean setType) { - normalTermination = setType; - } - - public boolean getTerminationType() { - return normalTermination; - } - - - public void addHostToSelectionPanel(int port, String hostname,String myHostName) { - if (rootSelectionPanel != null) { - rootSelectionPanel.checkBox(Integer.toString(port) + ":" + hostname + ":" + myHostName); - rootSelectionPanel.setButton(); - rootSelectionPanel.visible(); - } - } - - public void createRootSelectionPanel(CreateConnectionParam cp) { - rootSelectionPanel = new TreeVncRootSelectionPanel(); - rootSelectionPanel.setCp(cp); - } - + public void createRootSelectionPanel(CreateConnectionParam cp) { + rootSelectionPanel = new TreeVncRootSelectionPanel(); + rootSelectionPanel.setCp(cp); + } + public void close() { - // none - } - - public int getAcceptPort() { - return acceptPort; - } - - public boolean getReadyReconnect() { - return readyReconnect; - } + // none + } + + public int getAcceptPort() { + return acceptPort; + } + + public boolean getReadyReconnect() { + return readyReconnect; + } - public boolean getCuiVersion() { - return cuiVersion; - } - - public void setCuiVersion(boolean flag) { - cuiVersion = flag; - } + public boolean getCuiVersion() { + return cuiVersion; + } - public void readCheckDelay(Reader reader) throws TransportException { - - } + public void setCuiVersion(boolean flag) { + cuiVersion = flag; + } + + public void readCheckDelay(Reader reader) throws TransportException { + + } - public synchronized void vncConnected(boolean ready) { - if (ready && reconnecting) { - Socket vncSocket = viewer.getVNCSocket(); - NetworkInterface ni = nets.getInterface(vncSocket); - if (ni!=null) { - vncInterface = ni.getName(); - System.out.println("VNCNetworkInterface :" + vncInterface); - } - sendDesktopSizeChange(reconnectingId); - reconnecting = false; - if (reconnectingId == 0) { - viewer.setVisible(false); - } - } - if (reconnectingId!=0) { - readyReconnect = ready; - if (ready) { - notifyAll(); - } - } - } + public synchronized void vncConnected(boolean ready) { + if (ready && reconnecting) { + Socket vncSocket = viewer.getVNCSocket(); + NetworkInterface ni = nets.getInterface(vncSocket); + if (ni!=null) { + vncInterface = ni.getName(); + System.out.println("VNCNetworkInterface :" + vncInterface); + } + sendDesktopSizeChange(reconnectingId); + reconnecting = false; + if (reconnectingId == 0) { + viewer.setVisible(false); + } + } + if (reconnectingId!=0) { + readyReconnect = ready; + if (ready) { + notifyAll(); + } + } + } - public synchronized void waitForVNCConnection() throws InterruptedException { - if (reconnectingId!=0) { - while (!readyReconnect) { - wait(); - } - } - } + public synchronized void waitForVNCConnection() throws InterruptedException { + if (reconnectingId!=0) { + while (!readyReconnect) { + wait(); + } + } + } - public void sendDesktopSizeChange(short id) { - LinkedList<ByteBuffer> desktopSize = new LinkedList<ByteBuffer>(); - int width = context.getFbWidth(); - int height = context.getFbHeight(); - desktopSize.add(new UpdateRectangleMessage(width, height, EncodingType.INIT_DATA, context.getInitData(),id).getMessage()); - addSerialNumber(desktopSize); - multicastqueue.put(desktopSize); - } + public void sendDesktopSizeChange(short id) { + LinkedList<ByteBuffer> desktopSize = new LinkedList<ByteBuffer>(); + int width = context.getFbWidth(); + int height = context.getFbHeight(); + desktopSize.add(new UpdateRectangleMessage(width, height, EncodingType.INIT_DATA, context.getInitData(),id).getMessage()); + addSerialNumber(desktopSize); + multicastqueue.put(desktopSize); + } - public void addSerialNumber(LinkedList<ByteBuffer> bufs) { - ByteBuffer serialNum = multicastqueue.allocate(8); - serialNum.putLong(counter++); - serialNum.flip(); - bufs.addFirst(serialNum); - } + public void addSerialNumber(LinkedList<ByteBuffer> bufs) { + ByteBuffer serialNum = multicastqueue.allocate(8); + serialNum.putLong(counter++); + serialNum.flip(); + bufs.addFirst(serialNum); + } public void resetDecoder() { @@ -505,7 +505,7 @@ */ public int unzip(Inflater inflater, LinkedList<ByteBuffer> inputs, int inputIndex, byte[] bytes, int bufSize) - throws DataFormatException { + throws DataFormatException { int position = 0; int limit = bytes.length; while (inputIndex < inputs.size()) { @@ -518,9 +518,9 @@ int len0 = inflater.inflate(bytes, position, limit-position); if (len0 > 0) { - position += len0; + position += len0; if (position > limit) { - throw new DataFormatException(); + throw new DataFormatException(); } } } while (!inflater.needsInput()); @@ -563,8 +563,8 @@ inputs.add(inputData); header.putInt(12, EncodingType.ZRLEE.getId()); // means - // recompress - // every time + // recompress + // every time // using new Deflecter every time is incompatible with the // protocol, clients have to be modified. Deflater nDeflater = deflater; // new Deflater(); @@ -608,17 +608,17 @@ // here. } - public void setId(short id) { - this.id = id; - } + public void setId(short id) { + this.id = id; + } - public short getId() { - return id; - } + public short getId() { + return id; + } public void setMyAddress(String myHostName) { this.myAddress = myHostName; - + } public void setLeader(boolean leader) { @@ -630,9 +630,9 @@ } public void setTreeManager(String intf, TreeManagement clients) { - nets.setTreeManager(intf, clients); + nets.setTreeManager(intf, clients); } - + public TreeManagement getTreeManager(String intf) { return nets.getTreeManager(intf); } @@ -651,16 +651,16 @@ * @throws InterruptedException */ public void changeVNCServer(ViewerInterface vncProxyService, String hostName, int width, int height, short id) - throws UnknownHostException, IOException, InterruptedException { - // stop reader stop + throws UnknownHostException, IOException, InterruptedException { + // stop reader stop stopReceiverTask(); reconnectingId = id; - vncProxyService.inhelitClients(vncProxyService, hostName); + vncProxyService.inhelitClients(vncProxyService, hostName); // after connecting VNC server, rfb send SEND_INIT_DATA command and wakes me up if necessary - reconnecting = true; - if (reconnectingId!=0) { - waitForVNCConnection(); - } + reconnecting = true; + if (reconnectingId!=0) { + waitForVNCConnection(); + } } /** @@ -668,20 +668,20 @@ * run rootFinderListener if necessary */ public void createConnectionAndStart(ViewerInterface v) { - selectPort(ConnectionParams.DEFAULT_VNC_ROOT); + selectPort(ConnectionParams.DEFAULT_VNC_ROOT); startTreeVncCommandListener(); - if(isTreeManager() && firstTime) { - getCast = new TreeRootFinderListener(v); - Thread thread = new Thread(getCast, "tree-root-find-listener"); - thread.start(); - firstTime = false; - } + if(isTreeManager() && firstTime) { + getCast = new TreeRootFinderListener(v); + Thread thread = new Thread(getCast, "tree-root-find-listener"); + thread.start(); + firstTime = false; + } } - public void startTreeVncCommandListener() { + public void startTreeVncCommandListener() { acceptThread = new TreeVncCommandChannelListener(this, getAcceptPort()); - Thread thread = new Thread(acceptThread, "TreeVNC-accept"); - thread.start(); + Thread thread = new Thread(acceptThread, "TreeVNC-accept"); + thread.start(); } public TreeVncCommandChannelListener getAcceptThread() { @@ -708,14 +708,14 @@ reconnecting = b; } - public int getReconnectingId() { - return reconnectingId; - } - + public int getReconnectingId() { + return reconnectingId; + } + - public void setShowTree(boolean showTree) { - showTreeNode = showTree; - } + public void setShowTree(boolean showTree) { + showTreeNode = showTree; + } - + }