changeset 133:70cbec526039

connection handling
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sat, 07 Jun 2014 12:54:44 +0900
parents 84f167f9956a
children 128cce60c43c
files Todo.txt src/main/java/com/glavsoft/rfb/protocol/ReceiverTask.java src/main/java/jp/ac/u_ryukyu/treevnc/AcceptThread.java src/main/java/jp/ac/u_ryukyu/treevnc/MyRfbProto.java src/main/java/jp/ac/u_ryukyu/treevnc/client/TreeVncProtocol.java src/main/java/jp/ac/u_ryukyu/treevnc/server/AcceptClient.java src/main/java/jp/ac/u_ryukyu/treevnc/server/VncProxyService.java
diffstat 7 files changed, 134 insertions(+), 96 deletions(-) [+]
line wrap: on
line diff
--- a/Todo.txt	Sat Jun 07 01:57:58 2014 +0900
+++ b/Todo.txt	Sat Jun 07 12:54:44 2014 +0900
@@ -1,4 +1,4 @@
-Fri May 23 19:32:24 JST 2014
+Sat Jun  7 11:47:56 JST 2014
 
     Multicast で root を探す  (FIND_ROOT)
     その時に、自分の proxy port/host を付けておく
@@ -9,23 +9,34 @@
     そこから、root は、どこに接続に行くかを教えてくれる (CONNECT_TO)
     今度は、そこにclientとして接続する   (VERSION_MESSAGE )
 
+        FIND_ROOT         (client multicast )           :    int port; String hostname  (client's address)
+
     proxy port への接続では、client は自分から書かずに server からの version message を待つ
     普通のVNCは cliet からは VERSION_MESSAGE が行くが、Tree VNC では、
 
-        FIND_ROOT_REPLY   (root to client proxy port)
-        WHERE_TO_CONNECT  (clinet to root proxy port)
-        CONNECT_TO        (root to client )
+        FIND_ROOT_REPLY   (root to client proxy port)   :    int port; String hostname  (root's address)
+        WHERE_TO_CONNECT  (clinet to root proxy port)   :    int port; String hostname  (client's address)
+        CONNECT_TO        (root to client )             :    int port; String parentAddress (parent's address)
+        CONNECT_TO_AS_LEADER  (root to client )         :    int port; String parentAddress (parent's address)
 
     が来ることになる。
 
     切断時は、子供のleaderが root のproxy port に聞きに行く
 
-        LOST_PARENT       (root to client )
+        LOST_PARENT            (client to root)         :    int port; String hostname
 
     root は、接続変更が必要な node の proxy に CONNECT_TO を送る (木経由では送れない。切断されているので)
 
     最終的な切断時では、 LOST_PARENT が大量に出てしまうはず。なので、CONNECT_TO は連続しては送らない。
 
+    reportLastNode は CONNECT_TO で良い。(10001 port)
+    lostNodeConnection でも CONNECT_TO を使う
+
+    LOST_PARENT と PARENT_NOT_FOUND の違いはなんだ? LOST_PARENT は leader が出すようだけど。
+
+    CONNECT_TO で parentNum とか treeNum を送る必要はない。root 内部で接続アドレスから判断する。
+    なので、LOST_PARENT  は hostname と port だけでよい。
+
 Fri May 23 19:32:24 JST 2014
 
     checkdelay を再実装する
--- a/src/main/java/com/glavsoft/rfb/protocol/ReceiverTask.java	Sat Jun 07 01:57:58 2014 +0900
+++ b/src/main/java/com/glavsoft/rfb/protocol/ReceiverTask.java	Sat Jun 07 12:54:44 2014 +0900
@@ -41,6 +41,7 @@
 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;
@@ -147,7 +148,7 @@
 					logger.severe("Unsupported server message. Id = " + messageId);
 				}
 			} catch (TransportException e) {
-				logger.severe("Close session: " + e.getMessage());
+                logger.severe("Close session: " + e.getMessage());
 				if(!rfb.isRoot() && !(rfb.getTerminationType())) {
 					System.out.println("task stop");
 					int counter = 0;  // static int ?
@@ -158,7 +159,11 @@
 						if(counter > 3) {
 							echo.notfoundParent();
 						}
-						if(echo.lostHost()) break;
+						try {
+                            if(echo.lostHost()) break;
+                        } catch (Exception e1) {
+                            logger.severe("Cannot send lostHost: " + e1.getMessage());
+                        }
 						counter++;
 					}
 				} else if (isRunning) {
--- a/src/main/java/jp/ac/u_ryukyu/treevnc/AcceptThread.java	Sat Jun 07 01:57:58 2014 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/AcceptThread.java	Sat Jun 07 12:54:44 2014 +0900
@@ -35,7 +35,7 @@
 				InputStream is = newCli.getInputStream();
 				rfb.newClient(this, newCli, new Writer(os), new Reader(is));
 			} catch (Exception e) {
-				break;
+			    // logger
 			}
 		}
 	}
--- a/src/main/java/jp/ac/u_ryukyu/treevnc/MyRfbProto.java	Sat Jun 07 01:57:58 2014 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/MyRfbProto.java	Sat Jun 07 12:54:44 2014 +0900
@@ -1,11 +1,12 @@
 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.net.SocketException;
+import java.net.UnknownHostException;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.util.LinkedList;
@@ -38,7 +39,7 @@
 	public MulticastQueue<LinkedList<ByteBuffer>> multicastqueue = new MulticastQueue<LinkedList<ByteBuffer>>();
 	private RequestScreenThread rThread;
 	private boolean proxyFlag = true;
-	private TreeVncProtocol echo;
+	public TreeVncProtocol treeProtocol;
 	private String proxyAddr;
 	public int acceptPort = 0;
 	protected boolean readyReconnect = false;
@@ -87,8 +88,10 @@
 	 * @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) {
+	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);
@@ -108,14 +111,38 @@
 		case ProtocolContext.FIND_ROOT_REPLY :
 			handleFindRootReply(port,hostname);
 			break;
-		case ProtocolContext.FIND_ROOT : 
-		case ProtocolContext.WHERE_TO_CONNECT : 
+        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 : 
 		case ProtocolContext.LOST_PARENT :
 			System.out.println("get treeVNC command" + command);
 		}
 	}
 
 	/**
+	 * 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
@@ -135,15 +162,21 @@
 	 * @throws IOException
 	 * @throws TransportException
 	 */
-	public void newClient(AcceptThread acceptThread, final Socket newCli,
-			final Writer os, final Reader is) throws IOException, TransportException {
+	public void newClient(AcceptThread acceptThread, final Socket newCli,final Writer os, final Reader is) { 
 
-		
-		if (initialConnection(os, is)) {
-		    // TreeVNC command is processed
-		    newCli.close();
-		    return; 
-		}
+		try {
+            if (initialConnection(os, is)) {
+                // TreeVNC command is processed
+                newCli.close();
+                return; 
+            }
+        } catch (Exception e) {
+            try {
+                newCli.close();
+            } catch (IOException e1) {
+                // log
+            }
+        }
 			
 		final int myId = clients;
 		final MulticastQueue.Client<LinkedList<ByteBuffer>> c = multicastqueue.newClient();
@@ -467,19 +500,19 @@
 	}
 
 	public void setEcho(TreeVncProtocol _echo) {
-		echo = _echo;
+		treeProtocol = _echo;
 	}
 	
 	public void setViewer(ViewerImpl v) {
-		echo.setViewer(v);
+		treeProtocol.setViewer(v);
 	}
 	
 	public ViewerImpl getViewer() {
-		return echo.getViewer();
+		return treeProtocol.getViewer();
 	}
 	
 	public TreeVncProtocol getEcho() {
-		return echo;
+		return treeProtocol;
 	}
 
 	public void setTerminationType(boolean setType) {
@@ -578,7 +611,7 @@
     }
 
     public String getMyAddress() {
-        return echo.getMyAddress();
+        return treeProtocol.getMyAddress();
     }
 
     /**
--- a/src/main/java/jp/ac/u_ryukyu/treevnc/client/TreeVncProtocol.java	Sat Jun 07 01:57:58 2014 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/client/TreeVncProtocol.java	Sat Jun 07 12:54:44 2014 +0900
@@ -4,7 +4,6 @@
 import java.net.*;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
-
 import com.glavsoft.rfb.protocol.ProtocolContext;
 import com.glavsoft.viewer.ViewerImpl;
 
@@ -16,12 +15,12 @@
 	private boolean runflag = false;
 	private ReconnectionWaiter waitReply;
 	private Socket clientSocket = null;
-	private int echoPort = 9999;
+	private int echoPort;
 	public ViewerImpl client;
 	private String parentAddress;
 	public String parentNum;
 	public String treeNum;
-	public String leaderFlag;
+	public boolean leaderFlag;
 	private String myAddress;	
 	
 	public TreeVncProtocol(String name, int echoPort) {
@@ -29,6 +28,10 @@
 		this.proxyName = name;
 	}
 
+	public void setLeader(boolean f) {
+	    leaderFlag = f;
+	}
+	
 	public void openport() {
 		try {
 			echoSocket = new Socket(proxyName, echoPort);
@@ -52,30 +55,39 @@
 	public void whereToConnect(String hostname, int port) throws IOException {
 		sendWithHostAndPort(ProtocolContext.WHERE_TO_CONNECT, hostname, port);
 	}
-	
-	public void connectTo(String hostname, int port) throws IOException{
-		sendWithHostAndPort(ProtocolContext.CONNECT_TO, hostname, port);
+
+	public void connectTo(String hostname, int port,int leaderFlag) throws IOException{
+	    int command = ProtocolContext.CONNECT_TO;
+	    openport();
+	    ByteBuffer buf = ByteBuffer.allocate(4+4+4+4+hostname.length());
+	    buf.order(ByteOrder.BIG_ENDIAN);
+	    buf.put((byte) command);
+
+	    buf.put((byte) 0);
+	    buf.put((byte) 0);
+	    buf.put((byte) 0);
+	    buf.putInt(leaderFlag);
+	    buf.putInt(4+hostname.length()); // length
+	    buf.putInt(port);
+	    buf.put(hostname.getBytes(), 0, hostname.length());
+	    sendCommandToTheRoot(buf);
 	}
-	
-	public void connectToAsLeader(String hostname, int port) throws IOException {
-		sendWithHostAndPort(ProtocolContext.CONNECT_TO_AS_LEADER, hostname, port);
-	}
+
+    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);
 	}
-	
-
-    private void notFoundParent(int p) throws IOException {
-        sendWithHostAndPort(ProtocolContext.NOT_FOUND_PARENT, "", p);
-    }
-
 	public void sendWithHostAndPort(int command, String hostname, int port)
 			throws IOException {
-		
-		int savePort = echoPort;
 		openport();
-		
 		ByteBuffer buf = ByteBuffer.allocate(4+4+4+hostname.length());
 		buf.order(ByteOrder.BIG_ENDIAN);
 		buf.put((byte) command);
@@ -86,14 +98,7 @@
 		buf.putInt(4+hostname.length()); // length
 		buf.putInt(port);
 		buf.put(hostname.getBytes(), 0, hostname.length());
-		buf.flip();
-		
-		char[] charBuf = new char[12];
-		is.read(charBuf , 0, 12);
-		os.write(buf.array(), 0, buf.limit());
-		
-		echoPort = savePort;
-		streamClose();
+		sendCommandToTheRoot(buf);
 	}
 	
 
@@ -137,7 +142,7 @@
 	    if (runflag) return true;
 	    if ("1".equals(leaderFlag)) {
 	        openport();
-            lostParent(treeNum,Integer.parseInt(parentNum));   // "1"
+            lostParent(treeNum,Integer.parseInt(parentNum));  
 	        streamClose();
 	    }
 		return true;
@@ -147,7 +152,7 @@
 	    openport();
 	    runflag = true;
 	    try {
-	        notFoundParent(Integer.parseInt(parentNum)); // 2
+	        lostParent(treeNum, Integer.parseInt(parentNum)); // 2
 	    } catch (Exception e) {
 	    }   
 	    return true;
@@ -176,31 +181,14 @@
 		if ((treeNum = is.readLine()) != null) {
 			System.out.println("treenum: " + treeNum);
 		}
-		if ((leaderFlag = is.readLine()) != null) {
-			System.out.println("leaderflag: " + leaderFlag);
-		}
+//		if ((leaderFlag = is.readLine()) != null) {
+//			System.out.println("leaderflag: " + leaderFlag);
+//		}
 		InetAddress parent = soc.getInetAddress();
 		parentAddress = parent.getHostName();
         System.out.println("Actual Server: " + parentAddress);
 	}
-
-	void reConnectionMain(Socket echoSocket) {
-		while (true) {
-			try {
-				client.closeApp();
-				// set Socket for connection in VncViewer.
-				Socket soc = createSocketForClient(echoSocket, false);
-				client.setSocket(soc);
-				if (soc != null) 
-					client.run();
-				break;
-			} catch (IOException e) {
-				break;
-				// continue;
-			}
-		}
-	}
-
+	
 	void streamClose() throws IOException {
 		os.close();
 		is.close();
@@ -257,7 +245,6 @@
 
 	// create socket for ReConnection.
 	public Socket createSocketForClient(Socket soc, boolean flag) throws IOException {
-		Socket socket = null;
 		String parentAddress;
 		int count = 0;
 		System.out.println("########################PATH************************");
@@ -289,7 +276,7 @@
 				return null;
 			 is.readLine();// parentNum
 		}
-		socket = new Socket(parentAddress, Integer.parseInt(port));
+		Socket socket = new Socket(parentAddress, Integer.parseInt(port));
 		socket.setReuseAddress(true);
 		System.out.println("Return Soket");
 		return socket;
@@ -299,4 +286,22 @@
 		return parentAddress;
 	}
 
+	/**
+	 * Start client with new parent (including reconnection) 
+	 * @param port
+	 * @param hostname
+	 * @param leader
+	 * @throws IOException
+	 */
+    public void connectToParenet(int port, String hostname, boolean leader)
+            throws IOException {
+        this.leaderFlag = leader;
+        Socket socket = new Socket(hostname,port);
+        socket.setReuseAddress(true);
+        client.setTeminationType(true);
+        client.closeApp();
+        client.setSocket(socket);
+        client.run();
+    }
+
 }
\ No newline at end of file
--- a/src/main/java/jp/ac/u_ryukyu/treevnc/server/AcceptClient.java	Sat Jun 07 01:57:58 2014 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/server/AcceptClient.java	Sat Jun 07 12:54:44 2014 +0900
@@ -217,7 +217,7 @@
 			os.writeBytes(newpnum + "\n");
 			// os.writeBytes(newtreenum + "\n");
 			// os.writeBytes(newleaderflag + "\n");
-			// wait for last node connection.
+			// wait for last node connection
 			is.readLine();
 			is.close();
 			os.close();
@@ -230,22 +230,6 @@
 		}
 	}
 
-	void reportFinishFlag(String nextLastNode) {
-		Socket echoSocket;
-		try {
-			echoSocket = new Socket(nextLastNode, 10001);
-			DataOutputStream os = new DataOutputStream(
-					echoSocket.getOutputStream());
-			os.writeBytes("lastnode" + "\n");
-		} catch (UnknownHostException e) {
-			e.printStackTrace();
-		} catch (IOException e) {
-			e.printStackTrace();
-		}
-
-	}
-
-
 	public LinkedList<TreeVNCNode> getList() {
 		return nodeList;
 	}
--- a/src/main/java/jp/ac/u_ryukyu/treevnc/server/VncProxyService.java	Sat Jun 07 01:57:58 2014 +0900
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/server/VncProxyService.java	Sat Jun 07 12:54:44 2014 +0900
@@ -204,7 +204,7 @@
 		myRfb.sendDesktopSizeChange();
 	}
 
-	public  LinkedList<String> clientList() {
+	public  LinkedList<TreeVNCNode> clientList() {
 		return clients.getList();
 	}