diff src/main/java/ac/ryukyu/treevnc/server/AcceptClient.java @ 11:57ae9fbb1245

add files
author Taninari YU <you@cr.ie.u-ryukyu.ac.jp>
date Tue, 21 Aug 2012 14:02:05 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/ac/ryukyu/treevnc/server/AcceptClient.java	Tue Aug 21 14:02:05 2012 +0900
@@ -0,0 +1,303 @@
+package ac.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 counter = 0, parentnum = 0 /* 落ちたときの親の番号をカウントするためのもの */;
+	private LinkedList<String> ls = new LinkedList<String>();
+	private boolean addrRegistor = true;
+	private int passNumber=0,numberZone;
+	boolean runflag = false;
+	//private String name;
+	private int passCheck = 0;
+	private final int treebranch = 2; // treeの子ノードの数 
+	private String newparent,request,myAddress;
+	private String leaderflag = "0", sendleaderflag = "0";
+	private final int intv_time = 100;
+
+
+
+	public AcceptClient(String name) {
+		//this.name = name;
+	}
+
+
+	/*
+	public AcceptClient() {
+		new CreateThread(this);
+	}
+	*/
+
+	// public synchronized void transferParentAddrerss(BufferedReader
+	// is,PrintStream os) {
+	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 void displyLinkedList( LinkedList<String> ls) {
+		int g = 0;
+		for (String bs : ls) {
+			System.out.println(g + "number" + bs);
+			g++;
+		}
+	}
+
+	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,String treeNumber) throws IOException, InterruptedException {
+		os.println(ls.getLast());
+		replyNodeInformation(port);
+		counter--;
+		passCheck = 1;
+		reportLastNode(ls.getLast(), newparent,port, String.valueOf(parentnum),sendleaderflag);
+		listupdate(port);
+		waitThread();
+		/*
+		if (Integer.parseInt(treeNumber)==ls.size()-1)
+			return;
+			*/
+		//displyLinkedList(ls);
+		os.println(port);
+		leaderflag = decisionLeader(Integer.parseInt(treeNumber),treebranch);
+		os.println(treeNumber);
+		Thread.sleep(intv_time);
+		is.close();
+		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);
+			counter++;
+		} else {
+			return true;
+		}
+		
+		if (counter >= treebranch + 1) {
+			leaderflag = decisionLeader(counter, treebranch);
+			parentnum = (counter - 1) / treebranch;
+			request = ls.get(parentnum);
+			System.out.println(parentnum);
+			outputStream(os, request,String.valueOf(parentnum),
+					String.valueOf(counter), leaderflag);
+			checkParameter(parentnum, counter, leaderflag);
+		} else {
+			// treeの親ノードに接続する人に接続する人を教える
+			outputStream(os, myAddress, "0",
+					String.valueOf(counter), 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));//
+			// i+1は実験中に同じマシーンを使っていたのでportを変えて対応、本番時には取り除く予定。
+			echoSocket = new Socket(newchild, 10001);
+			DataOutputStream os = new DataOutputStream(echoSocket.getOutputStream());
+			os.writeBytes(newparent + "\n");
+			os.writeBytes(newpnum + "\n");
+			os.writeBytes(newtreenum + "\n");
+			os.writeBytes(newleaderflag + "\n");
+			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();
+		}
+
+	}
+	
+	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);
+			//System.out.println(treeNum + "--wait--");
+			replyLeaderNode(os,is,port,String.valueOf(treeNum));
+			notifyAll();
+			passNumber = 0;
+		} else if (numberZone == ((treeNum - 1) / treebranch)) {
+			if (++passNumber == treebranch) {
+				//System.out.println(treeNum + "--notify--");
+				passNumber = 0;
+				replyNormalChildren(os,is,port,String.valueOf(treeNum),true);
+			} else {
+				//System.out.println(treeNum + "--waityobi--");
+				replyNormalChildren(os,is,port,String.valueOf(treeNum),false);
+				wait(TIMEOUT);
+			}
+		} else {
+			wait();
+			checkWait(os,is,port,treeNum);
+		}
+	}
+	
+	private void waitThread() {
+		final int TIMEOUT = 3000;
+		try {
+			wait(TIMEOUT);
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+		}
+	}
+	private void notifyThread() {
+		notifyAll();
+	}
+ }
\ No newline at end of file