# HG changeset patch # User Shinji KONO # Date 1402138467 -32400 # Node ID ada4d850a820bb55a1e5b0c7f11fd386908046bf # Parent 128cce60c43c47aa11c4aea6da87a68eb47610be lostParent and notFoundParenet diff -r 128cce60c43c -r ada4d850a820 src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEESender.java --- a/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEESender.java Sat Jun 07 15:57:03 2014 +0900 +++ b/src/main/java/com/glavsoft/rfb/encoding/decoder/ZRLEESender.java Sat Jun 07 19:54:27 2014 +0900 @@ -1,7 +1,6 @@ package com.glavsoft.rfb.encoding.decoder; import jp.ac.u_ryukyu.treevnc.MyRfbProto; -import jp.ac.u_ryukyu.treevnc.client.MyRfbProtoClient; import com.glavsoft.drawing.Renderer; import com.glavsoft.exceptions.TransportException; @@ -24,7 +23,9 @@ FramebufferUpdateRectangle rect) throws TransportException { int dataLen = getZrleLength(rect, reader); reader.reset(); + // TreeVNC handling rfb.readSendData(dataLen, reader); + // reader is reseted read again if (! rfb.isRoot()) { // decode data when it is a client diff -r 128cce60c43c -r ada4d850a820 src/main/java/com/glavsoft/rfb/protocol/ReceiverTask.java --- a/src/main/java/com/glavsoft/rfb/protocol/ReceiverTask.java Sat Jun 07 15:57:03 2014 +0900 +++ b/src/main/java/com/glavsoft/rfb/protocol/ReceiverTask.java Sat Jun 07 19:54:27 2014 +0900 @@ -41,7 +41,6 @@ import com.glavsoft.rfb.encoding.decoder.ZRLEESender; import com.glavsoft.transport.Reader; -import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.util.logging.Logger; @@ -153,14 +152,13 @@ System.out.println("task stop"); int counter = 0; // static int ? TreeVncProtocol echo = rfb.getEcho(); - echo.openport(); while(true) { // after set time out. not counter. - if(counter > 3) { + if (counter > 3) { echo.notfoundParent(); } try { - if(echo.lostHost()) break; + if (echo.lostHost()) break; } catch (Exception e1) { logger.severe("Cannot send lostHost: " + e1.getMessage()); } @@ -223,7 +221,7 @@ Decoder decoder = decoders.getDecoderByType(rect.getEncodingType()); logger.finest(rect.toString() + (0 == numberOfRectangles ? "\n---" : "")); if (decoder != null) { - decoder.decode(reader, renderer, rect); + decoder.decode(reader, renderer, rect); // TreeVNC processing here if(!(rfb.getCuiVersion())) repaintController.repaintBitmap(rect); } else if (rect.getEncodingType() == EncodingType.RICH_CURSOR) { diff -r 128cce60c43c -r ada4d850a820 src/main/java/jp/ac/u_ryukyu/treevnc/MyRfbProto.java --- a/src/main/java/jp/ac/u_ryukyu/treevnc/MyRfbProto.java Sat Jun 07 15:57:03 2014 +0900 +++ b/src/main/java/jp/ac/u_ryukyu/treevnc/MyRfbProto.java Sat Jun 07 19:54:27 2014 +0900 @@ -5,8 +5,6 @@ import java.net.BindException; import java.net.ServerSocket; import java.net.Socket; -import java.net.SocketException; -import java.net.UnknownHostException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.LinkedList; @@ -39,18 +37,19 @@ public MulticastQueue> multicastqueue = new MulticastQueue>(); private RequestScreenThread rThread; private boolean proxyFlag = true; - public TreeVncProtocol treeProtocol; public int acceptPort = 0; protected boolean readyReconnect = false; private boolean cuiVersion; private long counter = 0; // packet serial number - private VncProxyService viewer = null; + TreeVncProtocol treeProtocol; + public TReeVNCCommand treeVncCommand; public ServerSocket servSock; private boolean permitChangeScreen = true; private static final int INFLATE_BUFSIZE = 1024 * 100; private Inflater inflater = new Inflater(); private Deflater deflater = new Deflater(); + private VncProxyService viewer; public MyRfbProto() { @@ -58,7 +57,8 @@ } public void setVncProxy(VncProxyService viewer) { - this.viewer = viewer; + this.viewer = viewer; + treeVncCommand = new TReeVNCCommand(viewer,this,treeProtocol); } abstract public boolean isRoot() ; @@ -71,7 +71,7 @@ sendRfbVersion(os); byte[] b; if ((b = readVersionMsg(is, os))!=null) { - treeVncCommand(b,is,os); + treeVncCommand.treeVncCommand(b,is,os); return true; } sendSecurityType(os); @@ -83,86 +83,6 @@ } /** - * handle TreeVNC Command - * @param b 12byte header ( command 4byte, length 4byte, port 4byte, option String ) - * @param is - * @param os - * @throws TransportException - * @throws IOException - */ - private void treeVncCommand(byte[] b, Reader is, Writer os) throws TransportException, IOException { - ByteBuffer buf = ByteBuffer.wrap(b); - int command = buf.get()&0xff; - buf.position(buf.position()+3); - int length = buf.getInt(); - int port = buf.getInt(); - String hostname = null; - if (length>12) { - byte namebuf[] = new byte[length-12]; - try { - is.readBytes(namebuf); - } catch (TransportException e) { - return; - } - hostname = new String(namebuf); - } - switch (command) { - case ProtocolContext.FIND_ROOT_REPLY : - handleFindRootReply(port,hostname); - break; - case ProtocolContext.CONNECT_TO_AS_LEADER : - handleConnectTo(port,hostname,true); - break; - case ProtocolContext.CONNECT_TO : - handleConnectTo(port,hostname,false); - break; - case ProtocolContext.FIND_ROOT : - // this is a multicast message, cannot happen - break; - case ProtocolContext.WHERE_TO_CONNECT : - handleWhereToConnect(port,hostname); - case ProtocolContext.LOST_PARENT : - System.out.println("get treeVNC command" + command); - } - } - - /** - * new clients ask root to where to connect - * tell him his parent - * @param port - * @param hostname - */ - private void handleWhereToConnect(int port, String hostname) { - viewer.replyCreateTree(hostname,port); - } - - /** - * set new parent address - * @param port - * @param hostname - * @param leader - * @throws IOException - * @throws SocketException - * @throws UnknownHostException - */ - private void handleConnectTo(int port, String hostname, boolean leader) throws UnknownHostException, SocketException, IOException { - if (isRoot()) { - return; // we don't have parent - } - treeProtocol.connectToParenet(port, hostname,leader); - } - - /** - * Accept FIND_ROOT_REPLY - * add replying TreeVNC root to RootSelection Panel - * @param port - * @param hostname - */ - private void handleFindRootReply(int port, String hostname) { - viewer.addHostToSelectionPanel(port, hostname); - } - - /** * handle new client accept * it also handle TreeVNC Command * @param acceptThread @@ -235,9 +155,10 @@ }; new Thread(timer, "timer-discard-multicastqueue").start(); /** - * send all incoming from clients to parent. + * handle command from lower node */ final Runnable reader = new Runnable() { + public void run() { for (;;) { try { @@ -291,7 +212,7 @@ }; /** - * send packets to a client + * send packets to a client (one thread for each client ) */ Runnable sender = new Runnable() { public void run() { @@ -301,8 +222,7 @@ // after this, we discard upward packet. new Thread(reader, "upward-packet-processing").start(); - // writeFramebufferUpdateRequest(0,0, framebufferWidth, - // framebufferHeight, false ); + for (;;) { LinkedList bufs = c.poll(); int inputIndex = 0; @@ -703,6 +623,13 @@ return len; } + /** + * read FrameBuffferUpdate. If it is ZLE, make it ZLEE which is self contained compressed packet. + * put the packet to the multicastqueue. Then normal rendering engine read the same stream using is.reset(). + * @param dataLen + * @param reader + * @throws TransportException + */ public void readSendData(int dataLen, Reader reader) throws TransportException { LinkedList bufs = new LinkedList(); diff -r 128cce60c43c -r ada4d850a820 src/main/java/jp/ac/u_ryukyu/treevnc/TReeVNCCommand.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/jp/ac/u_ryukyu/treevnc/TReeVNCCommand.java Sat Jun 07 19:54:27 2014 +0900 @@ -0,0 +1,138 @@ +package jp.ac.u_ryukyu.treevnc; + +import java.io.IOException; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; + +import com.glavsoft.exceptions.TransportException; +import com.glavsoft.rfb.protocol.ProtocolContext; +import com.glavsoft.transport.Reader; +import com.glavsoft.transport.Writer; + +import jp.ac.u_ryukyu.treevnc.client.TreeVncProtocol; +import jp.ac.u_ryukyu.treevnc.server.VncProxyService; + +public class TReeVNCCommand { + public VncProxyService viewer; + MyRfbProto rfb; + private TreeVncProtocol treeProtocol; + + public TReeVNCCommand(VncProxyService viewer,MyRfbProto rfb, TreeVncProtocol treeProtocol) { + this.viewer = viewer; + this.rfb = rfb; + this.treeProtocol = treeProtocol; + } + + /** + * handle TreeVNC Command + * @param b 12byte header ( command 4byte, length 4byte, port 4byte, option String ) + * @param is + * @param os + * @throws TransportException + * @throws IOException + */ + void treeVncCommand(byte[] b, Reader is, Writer os) throws TransportException, IOException { + ByteBuffer buf = ByteBuffer.wrap(b); + int command = buf.get()&0xff; // make it unsigned + buf.position(buf.position()+3); + int length = buf.getInt(); + int port = buf.getInt(); + String hostname = null; + if (length>12) { + byte namebuf[] = new byte[length-12]; + try { + is.readBytes(namebuf); + } catch (TransportException e) { + return; + } + hostname = new String(namebuf); + } + switch (command) { + case ProtocolContext.FIND_ROOT_REPLY : + handleFindRootReply(port,hostname); + break; + case ProtocolContext.CONNECT_TO_AS_LEADER : + handleConnectTo( port,hostname,true); + break; + case ProtocolContext.CONNECT_TO : + handleConnectTo( port,hostname,false); + break; + case ProtocolContext.FIND_ROOT : + // this is a multicast message, cannot happen + break; + case ProtocolContext.WHERE_TO_CONNECT : + handleWhereToConnect(port,hostname); + break; + case ProtocolContext.LOST_PARENT : + handleLostParent(port,hostname); + break; + case ProtocolContext.NOT_FOUND_PARENT : + handleNotFoundParent(port,hostname); + break; + default: + System.out.println("unknown treeVNC command" + command); + } + } + + + /** + * new clients ask root to where to connect + * tell him his parent + * @param port + * @param hostname + */ + void handleWhereToConnect(int port, String hostname) { + viewer.replyCreateTree(hostname,port); + } + + /** + * set new parent address + * @param port + * @param hostname + * @param leader + * @throws IOException + * @throws SocketException + * @throws UnknownHostException + */ + void handleConnectTo(int port, String hostname, boolean leader) throws UnknownHostException, SocketException, IOException { + if (rfb.isRoot()) { + return; // we don't have parent + } + treeProtocol.connectToParenet(port, hostname,leader); + } + + /** + * Accept FIND_ROOT_REPLY + * add replying TreeVNC root to RootSelection Panel + * @param port + * @param hostname + */ + void handleFindRootReply(int port, String hostname) { + viewer.addHostToSelectionPanel(port, hostname); + } + + /** + * client node lost parent connection, send reconnection message. + * if root is not here, clients die themselves. + * @param port + * @param hostname + */ + private void handleLostParent(int port, String hostname) { + try { + treeProtocol.lostParent(hostname, port); + } catch (IOException e) { + // log + } + } + + /** + * Some parent is missing. Reorganize tree + * @param port + * @param hostname + */ + private void handleNotFoundParent(int port, String hostname) { + treeProtocol.notfoundParent(hostname, port); + } + +} \ No newline at end of file diff -r 128cce60c43c -r ada4d850a820 src/main/java/jp/ac/u_ryukyu/treevnc/client/MyRfbProtoClient.java --- a/src/main/java/jp/ac/u_ryukyu/treevnc/client/MyRfbProtoClient.java Sat Jun 07 15:57:03 2014 +0900 +++ b/src/main/java/jp/ac/u_ryukyu/treevnc/client/MyRfbProtoClient.java Sat Jun 07 19:54:27 2014 +0900 @@ -1,14 +1,7 @@ package jp.ac.u_ryukyu.treevnc.client; -import java.io.BufferedReader; -import java.io.DataOutputStream; import java.io.IOException; -import java.io.InputStreamReader; import java.io.OutputStream; -import java.net.Socket; -import java.net.UnknownHostException; -import java.nio.ByteBuffer; -import java.util.LinkedList; import jp.ac.u_ryukyu.treevnc.MyRfbProto; @@ -46,18 +39,6 @@ return false; } - public byte[] readEchoPort() throws Exception { - byte[] b = new byte[4]; - reader.readBytes(b, 0, b.length); - return b; - } - - - @Override - public Socket accept() throws IOException { - servSock.setReuseAddress(true); - return servSock.accept(); - } void sendInitData(OutputStream os) throws IOException { os.write(context.getInitData()); @@ -74,15 +55,6 @@ return normalTermination; } - @Override - public void close() { - try { - servSock.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - /* * measure client delay time using tree connection. It should be summed up in upward tree communication */ diff -r 128cce60c43c -r ada4d850a820 src/main/java/jp/ac/u_ryukyu/treevnc/client/TreeVncProtocol.java --- a/src/main/java/jp/ac/u_ryukyu/treevnc/client/TreeVncProtocol.java Sat Jun 07 15:57:03 2014 +0900 +++ b/src/main/java/jp/ac/u_ryukyu/treevnc/client/TreeVncProtocol.java Sat Jun 07 19:54:27 2014 +0900 @@ -4,11 +4,11 @@ import java.net.*; import java.nio.ByteBuffer; import java.nio.ByteOrder; + import com.glavsoft.rfb.protocol.ProtocolContext; import com.glavsoft.viewer.ViewerImpl; public class TreeVncProtocol { - private String proxyName; private BufferedReader is = null; private DataOutputStream os = null; private Socket echoSocket = null; @@ -24,7 +24,7 @@ public TreeVncProtocol(String name, int echoPort) { this.echoPort = echoPort; - this.proxyName = name; + this.parentAddress = name; } public void setLeader(boolean f) { @@ -33,15 +33,15 @@ public void openport() { try { - echoSocket = new Socket(proxyName, echoPort); + echoSocket = new Socket(parentAddress, echoPort); echoSocket.setReuseAddress(true); os = new DataOutputStream(echoSocket.getOutputStream()); is = new BufferedReader(new InputStreamReader( echoSocket.getInputStream())); } catch (UnknownHostException e) { - System.err.println("Don't know about host: "+proxyName); + System.err.println("Don't know about host: "+parentAddress); } catch (IOException e) { - System.out.println(proxyName + " Connection Faild"); + System.out.println(parentAddress + " Connection Faild"); System.exit(0); } @@ -72,18 +72,10 @@ sendCommandToTheRoot(buf); } - public void sendCommandToTheRoot(ByteBuffer buf) throws IOException { - buf.flip(); - - char[] charBuf = new char[12]; - is.read(charBuf , 0, 12); // skip root's version header - os.write(buf.array(), 0, buf.limit()); // send our command - streamClose(); - } - public void lostParent(String hostname, int port) throws IOException { sendWithHostAndPort(ProtocolContext.LOST_PARENT, hostname, port); } + public void sendWithHostAndPort(int command, String hostname, int port) throws IOException { openport(); @@ -99,7 +91,16 @@ buf.put(hostname.getBytes(), 0, hostname.length()); sendCommandToTheRoot(buf); } - + + public void sendCommandToTheRoot(ByteBuffer buf) throws IOException { + buf.flip(); + + char[] charBuf = new char[12]; + is.read(charBuf , 0, 12); // skip root's version header + os.write(buf.array(), 0, buf.limit()); // send our command + streamClose(); + } + /** * @param args @@ -125,9 +126,6 @@ } return this; } - - - /** * Call at lost host @@ -155,6 +153,10 @@ return true; } + public void notfoundParent(String hostname, int port) { + + } + public TreeVncProtocol Interruption(Socket _clientSocket) { clientSocket = _clientSocket; try { @@ -279,10 +281,13 @@ return socket; } - public String getParentsAddress() { + public String getParentAddress() { return parentAddress; } + public int getParentPort() { + return echoPort; + } /** * Start client with new parent (including reconnection) * @param port @@ -301,4 +306,5 @@ client.run(); } + } \ No newline at end of file diff -r 128cce60c43c -r ada4d850a820 src/main/java/jp/ac/u_ryukyu/treevnc/server/AcceptClient.java --- a/src/main/java/jp/ac/u_ryukyu/treevnc/server/AcceptClient.java Sat Jun 07 15:57:03 2014 +0900 +++ b/src/main/java/jp/ac/u_ryukyu/treevnc/server/AcceptClient.java Sat Jun 07 19:54:27 2014 +0900 @@ -15,7 +15,7 @@ private boolean addrRegistor = true; boolean runflag = false; private final int treebranch = 2; - private String newparent, request, myAddress; + private String myAddress; private int leaderflag = 0; private int sendleaderflag = 0; private final int intv_time = 100; @@ -38,9 +38,9 @@ replyLeaderNode(os, is, Integer.parseInt(port), Integer.parseInt(treeNumber)); } else if ("2".equals(line)) { // reply to not Found Parents - replyNodeInformation(Integer.parseInt(port)); + TreeVNCNode newparent = replyNodeInformation(Integer.parseInt(port)); listupdate(port, newparent); - outputStream(os, newparent, String.valueOf(parentnum), + outputStream(os, newparent.getHostname(), String.valueOf(parentnum), port, leaderflag==1?"1":"0"); os.close(); is.close(); @@ -87,9 +87,9 @@ nodeList.removeLast(); } - private synchronized void listupdate(String port, String myaddr) { + private synchronized void listupdate(String port, TreeVNCNode newparent) { nodeList.remove(Integer.parseInt(port)); - nodeList.add(Integer.parseInt(port), new TreeVNCNode(myaddr)); + nodeList.add(Integer.parseInt(port), newparent); nodeList.removeLast(); } @@ -132,10 +132,10 @@ return addr.getHostAddress(); } - private void replyNodeInformation(int port) { + private TreeVNCNode replyNodeInformation(int port) { parentnum = (port - 1) / treebranch; - newparent = nodeList.get(parentnum).getHostname(); sendleaderflag = decisionLeader(port, treebranch); + return nodeList.get(parentnum); } private synchronized void replyLeaderNode(PrintStream os, BufferedReader is, int port, int treeNumber) throws IOException, @@ -145,7 +145,7 @@ if(lastNode != checkSameHost){ os.println(lastNode); } - replyNodeInformation(port); + TreeVNCNode newparent = replyNodeInformation(port); nodeCounter--; reportLastNode(lastNode, newparent, port, parentnum, sendleaderflag); listupdate(port); @@ -179,7 +179,12 @@ } } } - + + /** + * Determin tree topology and send CONNECT_TO command + * @param hostname + * @param port + */ public void replyCreateTree(String hostname, int port) { if (addrRegistor == true) { nodeList.add(new TreeVNCNode(hostname,port)); @@ -192,9 +197,10 @@ if (nodeCounter >= treebranch + 1) { leaderflag = decisionLeader(nodeCounter, treebranch); parentnum = (nodeCounter - 1) / treebranch; - request = nodeList.get(parentnum).getHostname(); + String request = nodeList.get(parentnum).getHostname(); + int port1 = nodeList.get(parentnum).getPort(); checkParameter(parentnum, nodeCounter, leaderflag); - treeProtocol.connectTo(request,port,leaderflag); + treeProtocol.connectTo(request,port1,leaderflag); } else { // connect to me treeProtocol.connectTo(rfb.getMyAddress(),rfb.getAcceptPort(),leaderflag); @@ -204,14 +210,14 @@ } } - void reportLastNode(String newchild, String newparent, int newtreenum, + void reportLastNode(String newchild, TreeVNCNode newparent, int newtreenum, int newpnum, int newleaderflag) throws IOException { try { System.out.println(newchild + "connect"); Socket echoSocket = new Socket(newchild, 10001); DataOutputStream os = new DataOutputStream(echoSocket.getOutputStream()); BufferedReader is = new BufferedReader(new InputStreamReader(echoSocket.getInputStream())); - os.writeBytes(newparent + "\n"); + os.writeBytes(newparent .getHostname() + "\n"); os.writeBytes(this.defaultVNCport+"\n"); os.writeBytes(newpnum + "\n"); // os.writeBytes(newtreenum + "\n"); diff -r 128cce60c43c -r ada4d850a820 src/main/java/jp/ac/u_ryukyu/treevnc/server/TreeVNCNode.java --- a/src/main/java/jp/ac/u_ryukyu/treevnc/server/TreeVNCNode.java Sat Jun 07 15:57:03 2014 +0900 +++ b/src/main/java/jp/ac/u_ryukyu/treevnc/server/TreeVNCNode.java Sat Jun 07 19:54:27 2014 +0900 @@ -22,4 +22,8 @@ return hostname; } + public int getPort() { + return port; + } + }