view src/main/java/jp/ac/u_ryukyu/treevnc/client/TreeVncProtocol.java @ 143:4547543ca73c

findRootReply
author oc
date Thu, 12 Jun 2014 19:21:38 +0900
parents 81b558b38b9f
children 649794dfb9d5
line wrap: on
line source

package jp.ac.u_ryukyu.treevnc.client;

import java.io.*;
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 BufferedReader is = null;
	private DataOutputStream os = null;
	private Socket echoSocket = null;
	private boolean runflag = false;
	private Socket clientSocket = null;
	private int echoPort;
	public ViewerImpl client;
	private String parentAddress;
	public String parentNum;
	public String treeNum;
	public boolean leaderFlag;
	private String myAddress;	
	
	public TreeVncProtocol(String name, int echoPort) {
		this.echoPort = echoPort;
		this.parentAddress = name;
	}

	public void setLeader(boolean f) {
	    leaderFlag = f;
	}
	
	public void openport() {
		try {
			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: "+parentAddress);
		} catch (IOException e) {
			System.out.println(parentAddress + " Connection Faild");
			System.exit(0);
		}

	}

	public void findRootReply(String hostname, int port) throws IOException {
		sendWithHostAndPort(ProtocolContext.FIND_ROOT_REPLY, hostname, port);
	}

	public void whereToConnect(String hostname, int port) throws IOException {
		sendWithHostAndPort(ProtocolContext.WHERE_TO_CONNECT, 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) leaderFlag);
	    buf.put((byte) 0);
	    buf.put((byte) 0);
	    buf.putInt(4+hostname.length()); // length
	    buf.putInt(port);
	    buf.put(hostname.getBytes(), 0, hostname.length());
	    sendCommandToTheRoot(buf);
	}

	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();
		ByteBuffer buf = ByteBuffer.allocate(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(4+hostname.length()); // length
		buf.putInt(port);
		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();
    }


	/**
	 * Call at lost host
	 * @throws IOException 
	 * @throws NumberFormatException 
	 */
	public boolean lostHost() throws NumberFormatException, IOException {
	    openport();
	    if (runflag) return true;
	    if ("1".equals(leaderFlag)) {
	        openport();
            lostParent(treeNum,Integer.parseInt(parentNum));  
	        streamClose();
	    }
		return true;
	}

	public boolean notfoundParent() {
	    openport();
	    runflag = true;
	    try {
	        lostParent(treeNum, Integer.parseInt(parentNum)); // 2
	    } catch (Exception e) {
	    }   
	    return true;
	}

    public void notfoundParent(String hostname, int port) {

    }

	
	void streamClose() throws IOException {
		os.close();
		is.close();
		echoSocket.close();
	}

	public void setViewer(ViewerImpl v) {
		client = v;
	}
	
	public ViewerImpl getViewer() {
		return client;
	}

	public String getMyAddress() {
		return myAddress;
	}

	// create socket for ReConnection.
	public Socket createSocketForClient(Socket soc, boolean flag) throws IOException {
		String parentAddress;
		int count = 0;
		System.out.println("########################PATH************************");
		BufferedReader is = new BufferedReader(new InputStreamReader(soc.getInputStream()));
		parentAddress = is.readLine();
		String port = is.readLine();
		// It is called when the screen changes.
		if ("reconnection".equals(parentAddress)) {
			while (true) {
				try {
					client.setOpenPort(Integer.parseInt(port));
					System.out.println("----------:"+this.parentAddress+"----------:"+port);
					return new Socket(this.parentAddress,
							Integer.parseInt(port));
				} catch (IOException e) {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e1) {
						e1.printStackTrace();
					}
					if (count++ > 5)
						break;
					continue;
				}
			}
		} else {
			System.out.println("###########################faild" + parentAddress+"port::"+port);
			if (parentAddress == null)
				return null;
			 is.readLine();// parentNum
		}
		Socket socket = new Socket(parentAddress, Integer.parseInt(port));
		socket.setReuseAddress(true);
		System.out.println("Return Soket");
		return socket;
	}

	public String getParentAddress() {
		return parentAddress;
	}

    public int getParentPort() {
        return echoPort;
    }
    
	/**
	 * 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();
    }


}