view src/main/java/jp/ac/u_ryukyu/treevnc/server/AcceptClient.java @ 56:913d0f663e74

12/9
author one
date Mon, 09 Dec 2013 16:09:06 +0900
parents 0ae87c7e767c
children d9cf08c6415c
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<String> ls = new LinkedList<String>();
	private boolean addrRegistor = true;
	// private int passNumber=0,numberZone;
	boolean runflag = false;
	private int passCheck = 0;
	private final int treebranch = 2;
	private String newparent, request, myAddress;
	private String leaderflag = "0", sendleaderflag = "0";
	private final int intv_time = 100;
	private String port = "5999";

	public AcceptClient() {
		// this.name = name;
	}

	/*
	 * public AcceptClient() { new CreateThread(this); }
	 */

	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
					checkWait(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) {
		ls.remove(Integer.parseInt(port));
		ls.add(Integer.parseInt(port), ls.getLast());
		ls.removeLast();
	}

	private synchronized void listupdate(String port, String myaddr) {
		ls.remove(Integer.parseInt(port));
		ls.add(Integer.parseInt(port), myaddr);
		ls.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<String> ls) {
		if (line != null) {
			ls.add(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 new String(addr.getHostAddress());
	}

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

	private void replyLeaderNode(PrintStream os, BufferedReader is, String port, int treeNumber) throws IOException,
			InterruptedException {
		String lastNode = ls.getLast();
		if(lastNode != ls.get(treeNumber)){
			os.println(lastNode);
		}
		replyNodeInformation(port);
		nodeCounter--;
		passCheck = 1;
		reportLastNode(lastNode, newparent, port, String.valueOf(parentnum), sendleaderflag);
		listupdate(port);
		if(lastNode != ls.get(treeNumber)) {
			os.println(port);
			os.println(treeNumber);
		}
		leaderflag = decisionLeader(treeNumber, treebranch);
		lostNodeConnection(treeNumber, lastNode, port);
		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 = ls.get(treeNum + i);
			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();
			}
		}
	}

	private void replyNormalChildren(PrintStream os, BufferedReader is,
			String port, String treeNumber, boolean flag) throws IOException,
			InterruptedException {
		if (flag)
			notifyThread();
		else
			waitThread();
		if (Integer.parseInt(treeNumber) == ls.size())
			return;
		os.println(ls.get(Integer.parseInt(port)));
		os.println(port);
		if (ls.size() - 1 + passCheck == Integer.parseInt(treeNumber))
			treeNumber = "skip";
		passCheck = 0;
		os.println(treeNumber);
		System.out.println("num4=" + ls.get(Integer.parseInt(port)));
		runflag = false;
		is.close();
		os.close();
	}

	private synchronized boolean replyCreateTree(PrintStream os, String port,
			String line) throws InterruptedException {
		if (addrRegistor == true) {
			ls.add(myAddress);
			addrRegistor = false;
		}

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

		if (nodeCounter >= treebranch + 1) {
			leaderflag = decisionLeader(nodeCounter, treebranch);
			parentnum = (nodeCounter - 1) / treebranch;
			request = ls.get(parentnum);
			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 {
			Socket echoSocket;
			System.out.println(newchild + "connect");
			// echoSocket = new Socket(newchild, 10001 + (i + 1));
			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.port+"\n");
			os.writeBytes(newpnum + "\n");
			// os.writeBytes(newtreenum + "\n");
			// os.writeBytes(newleaderflag + "\n");
			// wait for last node connection.
			is.readLine();
			is.close();
			os.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");
		}
	}

	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();
		}

	}

	/*
	 * // previous viersion for reconnection. synchronized void
	 * checkWait(PrintStream os,BufferedReader is,String port,int treeNum)
	 * throws InterruptedException, IOException { final int TIMEOUT = 3000; if
	 * (passNumber == 0) { passNumber++; numberZone = ((treeNum - 1) /
	 * treebranch); replyLeaderNode(os,is,port,String.valueOf(treeNum));
	 * notifyAll(); passNumber = 0; } else if (numberZone == ((treeNum - 1) /
	 * treebranch)) { if (++passNumber == treebranch) { passNumber = 0;
	 * replyNormalChildren(os,is,port,String.valueOf(treeNum),true); } else {
	 * replyNormalChildren(os,is,port,String.valueOf(treeNum),false);
	 * wait(TIMEOUT); } } else { wait(); checkWait(os,is,port,treeNum); } }
	 */

	synchronized void checkWait(PrintStream os, BufferedReader is, String port,
			int treeNum) throws InterruptedException, IOException {
		replyLeaderNode(os, is, port, treeNum);
	}

	private void waitThread() {
		final int TIMEOUT = 3000;
		try {
			wait(TIMEOUT);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	private void notifyThread() {
		notifyAll();
	}

	public LinkedList<String> getList() {
		return ls;
	}

	public void setList(LinkedList<String> _ls) {
		ls = _ls;
	}

	public int getTreeBranch() {
		return treebranch;
	}
}