view src/main/java/jp/ac/u_ryukyu/treevnc/client/TreeVncProtocol.java @ 125:32c6563492f3

add vnc protocol command sender.
author oc
date Thu, 05 Jun 2014 18:30:45 +0900
parents src/main/java/jp/ac/u_ryukyu/treevnc/client/EchoClient.java@ca39d762805e
children cc1fcdc7657c
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 jp.ac.u_ryukyu.treevnc.server.VncProxyService;

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;
	private boolean runflag = false;
	private ReconnectionWaiter waitReply;
	private Socket clientSocket = null;
	private int echoPort = 9999;
	public ViewerImpl client;
	private String parentAddress;
	public String parentNum;
	public String treeNum;
	public String leaderFlag;
	private String myAddress;
	private int rootPort;
	
	
	public TreeVncProtocol(String name, int echoPort) {
		this.echoPort = echoPort;
		this.proxyName = name;
	}
	
	public void setRootPort(int port) {
		rootPort = port;
	}


	public void openport() {
		try {
			echoSocket = new Socket(proxyName, 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);
		} catch (IOException e) {
			System.out.println(proxyName + " 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) throws IOException{
		sendWithHostAndPort(ProtocolContext.CONNECT_TO, hostname, port);
	}
	
	public void connectToAsLeader(String hostname, int port) throws IOException {
		sendWithHostAndPort(ProtocolContext.CONNECT_TO_AS_LEADER, hostname, port);
	}

	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 {
		
		int savePort = echoPort;
		echoPort = rootPort;
		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());
		buf.flip();
		
		char[] charBuf = new char[12];
		is.read(charBuf , 0, 12);
		os.write(buf.array(), 0, buf.limit());
		
		echoPort = savePort;
		streamClose();
	}
	

	/**
	 * @param args
	 *            select connect port
	 * @return
	 */
	public TreeVncProtocol requestHostName(String args) {
		
		if (echoSocket != null && os != null && is != null) {
			try {
				InetAddress addr = echoSocket.getLocalAddress();
				myAddress = addr.getHostAddress();
				os.writeBytes(myAddress + "\n");
				os.writeBytes(args + "\n");
				getProxyData(is, echoSocket);

				streamClose();
			} catch (UnknownHostException e) {
				System.err.println("Trying to connect to unknown host: " + e);
			} catch (IOException e) {
				System.err.println("IOException: " + e);
			}
			waitReply = new ReconnectionWaiter(treeNum, this);
			waitReply.start();
		}
		return this;
	}
	

	

	/**
	 * Call at lost host
	 */
	public boolean lostHost() {
		if (echoSocket != null && os != null && is != null) {
			try {
				if (runflag) {
					return true;
				}
				sendDataProxy();
				reConnectionMain(echoSocket);
				streamClose();
			} catch (UnknownHostException e) {
				System.err.println("Trying to connect to unknown host: " + e);
			} catch (IOException e) {
				return false;
			} catch (NullPointerException e) {
				//openport();
				System.out.println("notFoundParents");
				//notfoundParent();
			}
		}
		return true;
	}

	public boolean notfoundParent() {
		if (echoSocket != null && os != null && is != null) {
			runflag = true;
			try {
				sendDataProxy("2", parentNum, null);
				getProxyData(is, echoSocket);
				reConnectionMain(echoSocket);
				streamClose();
			} catch (UnknownHostException e) {
				System.err.println("Trying to connect to unknown host: " + e);
			} catch (IOException e) {
				System.err.println("IOException: " + e);
			}
		}
		return true;
	}

	public TreeVncProtocol Interruption(Socket _clientSocket) {
		clientSocket = _clientSocket;
		try {
			BufferedReader lostis = new BufferedReader(new InputStreamReader(
					clientSocket.getInputStream()));
			getProxyData(lostis, clientSocket);
			clientSocket.close();
		} catch (IOException e) {
			System.out.println(e);
		}
		return this;
	}

	void getProxyData(BufferedReader is, Socket soc) throws IOException {
		if ((parentAddress = is.readLine()) != null) {
            System.out.println("Server received: " + parentAddress);
		}
		if ((parentNum = is.readLine()) != null) {
			System.out.println("parent: " + parentNum);
		}
		if ((treeNum = is.readLine()) != null) {
			System.out.println("treenum: " + treeNum);
		}
		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();
		echoSocket.close();
	}

	void sendDataProxy() {
		if ("1".equals(leaderFlag)) {
			sendDataProxy("1", parentNum, treeNum);
			System.out.println("---------------------------------------------");
		} else {
			// sendDataProxy("3", parentNum, treeNum);
			// System.out.println("---------------------------------------------");
		}
	}

	void sendDataProxy(String type, String num, String treenum) {
		try {
			if (treenum != null) {
				os.writeBytes(type + "\n");
				os.writeBytes(num + "\n");
				os.writeBytes(treenum + "\n");
			} else {
				os.writeBytes(type + "\n");
				os.writeBytes(num + "\n");
			}
		} catch (UnknownHostException e) {
			System.err.println("Trying to connect to unknown host: " + e);
		} catch (IOException e) {
			System.err.println("IOException: " + e);
		}
	}

	public void getParentName() {
		if (clientSocket == null) {
			openport();
			requestHostName("1"); // 1 is normal connection type.
		} else {
			Interruption(clientSocket);
		}
	}

	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 {
		Socket socket = null;
		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 = new Socket(parentAddress, Integer.parseInt(port));
		socket.setReuseAddress(true);
		System.out.println("Return Soket");
		return socket;
	}

	public String getParentsAddress() {
		return parentAddress;
	}

}