view src/myVncProxy/AcceptClient.java @ 152:fb1a62154851

merge 151
author Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
date Sat, 10 Sep 2011 04:16:19 +0900
parents db5f735fd2b4 ea60596e05ef
children 1c0af90f7f59
line wrap: on
line source

package myVncProxy;

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

public class AcceptClient {
	int counter = 0, parentnum = 0/* 落ちたときの親の番号をカウントするためのもの */;
	LinkedList<String> ls = new LinkedList<String>();
	boolean runflag = false;
	private String name;
	boolean addrRegistor = true;
	int passCheck = 0;

	public AcceptClient(String _name) {
		name = _name;
	}

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

	// public synchronized void transferParentAddrerss(BufferedReader
	// is,PrintStream os) {
	public synchronized void transferParentAddrerss(BufferedReader is,PrintStream os) {
		 String line, port;
		 int intv_time = 100;
		 String request;
		 int treebranch = 2;// treeの子ノードの数 
		 String leaderflag = "0", sendleaderflag = "0";
		
				// クライアントからのメッセージを待ち、受け取ったメッセージをそのまま返す
				try {
					while (true) {
						line = is.readLine();
						port = is.readLine();

						System.out.println("データーを受信しましたlin=" + line
								+ "       port=" + port);
						// 自分の IPADRESSを取得する
						InetAddress addr = InetAddress.getLocalHost();
						String myAddress = new String(addr.getHostAddress());

						if ("1".equals(line)) {
							System.out.println("親が落ちましたmessage" + port);
							String checkRepetition = is.readLine();
							os.println(ls.getLast());
							parentnum = (Integer.parseInt(port) - 1)
									/ treebranch;
							String newparent = ls.get(parentnum);

							counter--;
							runflag = true;

							sendleaderflag = decisionLeader(Integer.parseInt(port), treebranch);

							//waitreplyに向けて命令を送る。
							Child report = new Child();
							
							passCheck = 1;
							report.reportLastNode(ls.getLast(), newparent,port, 
									String.valueOf(parentnum),sendleaderflag, counter);
							
							listupdate(port);

							int g = 0;
							for (String bs : ls) {
								System.out.println(g + "番目" + bs);
								g++;
							}

							os.println(port);
							// os.println(leaderflag);

							leaderflag = decisionLeader(
									Integer.parseInt(checkRepetition),
									treebranch);

							if (Integer.parseInt(checkRepetition) == counter + 1) {
								checkRepetition = "stop";
							} else {
								checkRepetition = "go";
							}
							os.println(checkRepetition);

							// os.println(leaderflag);
							Thread.sleep(intv_time);
							is.close();
							os.close();

						} else if ("2".equals(line)) {
							parentnum = (Integer.parseInt(port) - 1) / treebranch;
							String newparent = ls.get(parentnum);
							leaderflag = decisionLeader(Integer.parseInt(port),treebranch);
							listupdate(port,newparent);
							outputStream(os, newparent,String.valueOf(parentnum),port,leaderflag);
							os.close();
							is.close();
						} else if ("3".equals(line)) {
							String checkRepetition = is.readLine();
							System.out.println("落ちたのを確認しました");

							os.println(ls.get(Integer.parseInt(port)));
							os.println(port);

							if (checkRepetition.equals(ls.getLast()))
								checkRepetition = "stop";
							} else {

								//checkRepetition = "go";
								if(ls.size()-1+passCheck == Integer.parseInt(checkRepetition)) {
									checkRepetition = "skip";

								}
								passCheck = 0;
							}
							os.println(checkRepetition);

							System.out.println("num4="
									+ ls.get(Integer.parseInt(port)));
							line = null;
							runflag = false;
							is.close();
							os.close();
						} else {
							if (addrRegistor == true) {
								ls.add(myAddress);
								addrRegistor = false;
							}

							if (line != null) {
								addClientAdress(line, ls);
								counter++;
							} else {
								break;
							}

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

				} catch (IOException e) {
					System.out.println(e);
				}

				catch (InterruptedException e) {
					e.printStackTrace();
				}
		
		
	}

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

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

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

	void addClientAdress(String line, LinkedList<String> ls) {
		int g = 0;
		if (line != null) {
			ls.add(line);
		}
		for (String bs : ls) {
			System.out.println(g + "番目" + bs);
			g++;
		}
	}

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

}

class Child {

	void reportLastNode(String hiddenchild, String newparent,
			String newtreenum, String newpnum, String newleaderflag, int i)
			throws IOException {
		try {
			Socket echoSocket;
			System.out.println(hiddenchild + "に接続します");
			echoSocket = new Socket(hiddenchild, 10001 + (i + 1));// i+1は実験中に同じマシーンを使っていたのでportを変えて対応、本番時には取り除く予定。

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

	}
}