view src/main/java/jp/ac/u_ryukyu/treevnc/server/AcceptClient.java @ 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
line wrap: on
line source

package jp.ac.u_ryukyu.treevnc.server;

import java.net.Socket;
import java.net.UnknownHostException;
import java.io.*;
import java.net.*;
import java.util.*;

public class AcceptClient {
	private int nodeCounter = 0, parentnum = 0;
	private LinkedList<TreeVNCNode> nodeList = new LinkedList<TreeVNCNode>();
	private boolean addrRegistor = true;
	boolean runflag = false;
	private final int treebranch = 2;
	private String newparent, request, myAddress;
	private String leaderflag = "0", sendleaderflag = "0";
	private final int intv_time = 100;
	private String defaultVNCport = "5999";

	public AcceptClient() {
	}
	
	public void transferParentAddrerss(BufferedReader is, PrintStream os) {
		try {
			while (true) {
				String line = is.readLine();
				String port = is.readLine();
				myAddress = getMyAddress();
				if ("1".equals(line) || "3".equals(line)) {
					String treeNumber = is.readLine();
					// reply to Parents lost node
					replyLeaderNode(os, is, port, Integer.parseInt(treeNumber));
				} else if ("2".equals(line)) {
					// reply to not Found Parents
					replyNodeInformation(port);
					listupdate(port, newparent);
					outputStream(os, newparent, String.valueOf(parentnum),
							port, leaderflag);
					os.close();
					is.close();
				} else if (line != null) {
					// connection First time
					if (checkAddress(line)) {
						outputStream(os, myAddress, "0", "0", "0");
						break;
					} else {
						if (replyCreateTree(os, port, line)) {
							break;
						} else {
							break;
						}
					}
				}
			}
		} catch (IOException e) {
			System.out.println(e);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	private boolean checkAddress(String line) {
		String test[] = line.split("\\.");
		int a = Integer.parseInt(test[0]);
		int b = Integer.parseInt(test[1]);
		if ((192 == a && b == 168) || (172 == a && (b > 15 || b < 32))
				|| 10 == a) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * @param port
	 *            parent value
	 */
	private synchronized void listupdate(String port) {
		nodeList.remove(Integer.parseInt(port));
		nodeList.add(Integer.parseInt(port), nodeList.getLast());
		nodeList.removeLast();
	}

	private synchronized void listupdate(String port, String myaddr) {
		nodeList.remove(Integer.parseInt(port));
		nodeList.add(Integer.parseInt(port), new TreeVNCNode(myaddr));
		nodeList.removeLast();
	}

	private void outputStream(PrintStream os, String request, String parentnum,
			String treenum, String leaderflag) {
		os.println(request);
		os.println(parentnum);
		os.println(treenum);
		os.println(leaderflag);
	}

	private void checkParameter(int parent, int counter, String leaderflag) {
		System.out.println("number p =" + parentnum);
		System.out.println("number i =" + counter);
		System.out.println("leaderflag=" + leaderflag + "\n");
	}

	private synchronized void addClientAdress(String line, LinkedList<TreeVNCNode> nodeList2) {
		if (line != null) {
			nodeList2.add(new TreeVNCNode(line));
		}
		// displyLinkedList(ls);
	}

	private String decisionLeader(int counter, int treebranch) {
		if ((counter - 1) % treebranch == 1) { // children in most young treenum
												// have leaderflag 1 other 0
			return "0";
		} else {
			return "1";
		}
	}

	String getMyAddress() {
		InetAddress addr = null;
		try {
			addr = InetAddress.getLocalHost();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		return addr.getHostAddress();
	}

	private void replyNodeInformation(String port) {
		parentnum = (Integer.parseInt(port) - 1) / treebranch;
		newparent = nodeList.get(parentnum).getHostname();
		sendleaderflag = decisionLeader(Integer.parseInt(port), treebranch);
	}

	private synchronized void replyLeaderNode(PrintStream os, BufferedReader is, String port, int treeNumber) throws IOException,
			InterruptedException {
		String lastNode = nodeList.getLast().getHostname();
		String checkSameHost = nodeList.get(treeNumber).getHostname();
		if(lastNode != checkSameHost){
			os.println(lastNode);
		}
		replyNodeInformation(port);
		nodeCounter--;
		reportLastNode(lastNode, newparent, port, String.valueOf(parentnum), sendleaderflag);
		listupdate(port);
		if(lastNode != checkSameHost) {
			os.println(this.defaultVNCport);
			os.println(treeNumber);
		}
		leaderflag = decisionLeader(treeNumber, treebranch);
		if(nodeList.size() > treeNumber +1)
			lostNodeConnection(treeNumber, lastNode, this.defaultVNCport);
		Thread.sleep(intv_time);
		is.close();
		os.close();
	}

	private void lostNodeConnection(int treeNum, String hostNode, String port)
			throws UnknownHostException, IOException {
		for (int i = 1; i < treebranch; i++) {
			String host = nodeList.get(treeNum + i).getHostname();
			if (host != hostNode) {
				System.out.println("connection socket for-------------------- " + host);
				Socket clients = new Socket(host, 10001);
				clients.setReuseAddress(true);
				DataOutputStream os = new DataOutputStream(clients.getOutputStream());
				System.out.println("hostnode" + hostNode + "::port" + port);
				os.writeBytes(hostNode + "\n");
				os.writeBytes(port+"\n");
				os.writeBytes(String.valueOf(treeNum + 1) + "\n");
				os.close();
				clients.close();
			}
		}
	}
	
	private synchronized boolean replyCreateTree(PrintStream os, String port,
			String line) throws InterruptedException {
		if (addrRegistor == true) {
			nodeList.add(new TreeVNCNode(myAddress));
			addrRegistor = false;
		}

		if (line != null) {
			addClientAdress(line, nodeList);
			nodeCounter++;
		} else {
			return true;
		}

		if (nodeCounter >= treebranch + 1) {
			leaderflag = decisionLeader(nodeCounter, treebranch);
			parentnum = (nodeCounter - 1) / treebranch;
			request = nodeList.get(parentnum).getHostname();
			System.out.println(parentnum);
			outputStream(os, request, String.valueOf(parentnum),
					String.valueOf(nodeCounter), leaderflag);
			checkParameter(parentnum, nodeCounter, leaderflag);
		} else {
			outputStream(os, myAddress, "0", String.valueOf(nodeCounter),
					leaderflag);
		}
		Thread.sleep(intv_time);
		return false;
	}

	void reportLastNode(String newchild, String newparent, String newtreenum,
			String newpnum, String 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(this.defaultVNCport+"\n");
			os.writeBytes(newpnum + "\n");
			// os.writeBytes(newtreenum + "\n");
			// os.writeBytes(newleaderflag + "\n");
			// wait for last node connection
			is.readLine();
			is.close();
			os.close();
			echoSocket.close();
		} catch (UnknownHostException e) {
			System.err.println("Don't know about host: localhost");
		} catch (IOException e) {
			System.err
					.println("Couldn't get I/O for the connection to: localhost");
		}
	}

	public LinkedList<TreeVNCNode> getList() {
		return nodeList;
	}

	public void setList(LinkedList<TreeVNCNode> _ls) {
		nodeList = _ls;
	}

	public int getTreeBranch() {
		return treebranch;
	}
}