changeset 11:57ae9fbb1245

add files
author Taninari YU <you@cr.ie.u-ryukyu.ac.jp>
date Tue, 21 Aug 2012 14:02:05 +0900
parents 73abb3b86ce7
children 12c3a73be47f
files src/main/java/ac/ryukyu/treevnc/client/MyVncClient.java src/main/java/ac/ryukyu/treevnc/server/AcceptClient.java src/main/java/ac/ryukyu/treevnc/server/AcceptThread.java src/main/java/ac/ryukyu/treevnc/server/BroadCastProxy.java src/main/java/ac/ryukyu/treevnc/server/CreateThread.java src/main/java/ac/ryukyu/treevnc/server/GetBroadCastProxy.java src/main/java/ac/ryukyu/treevnc/server/MyRfbProtoProxy.java src/main/java/ac/ryukyu/treevnc/server/RequestScreenThread.java src/main/java/ac/ryukyu/treevnc/server/TextBoxProxy.java src/main/java/ac/ryukyu/treevnc/server/VncProxyService.java src/main/java/jp/ac/u_ryukyu/treevnc/test/ThreadTest.java src/viewer_swing/java/com/glavsoft/viewer/ConnectionManager.java src/viewer_swing/java/com/glavsoft/viewer/TreeConnectionManager.java src/viewer_swing/java/com/glavsoft/viewer/Viewer.java
diffstat 14 files changed, 1696 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/ac/ryukyu/treevnc/client/MyVncClient.java	Wed Aug 15 17:08:10 2012 +0900
+++ b/src/main/java/ac/ryukyu/treevnc/client/MyVncClient.java	Tue Aug 21 14:02:05 2012 +0900
@@ -5,6 +5,8 @@
 import java.io.IOException;
 import java.util.logging.Logger;
 
+import javax.swing.SwingUtilities;
+
 
 import com.glavsoft.exceptions.AuthenticationFailedException;
 import com.glavsoft.exceptions.FatalException;
@@ -18,6 +20,7 @@
 import com.glavsoft.transport.Reader;
 import com.glavsoft.transport.Writer;
 import com.glavsoft.viewer.ConnectionManager;
+import com.glavsoft.viewer.TreeConnectionManager;
 import com.glavsoft.viewer.Viewer;
 import com.glavsoft.viewer.cli.Parser;
 import com.glavsoft.viewer.swing.ClipboardControllerImpl;
@@ -45,12 +48,14 @@
 	private final ProtocolSettings settings;
 	private final UiSettings uiSettings;
 	private String[] arguments;
+	private TreeConnectionManager treeConnectionManager;
 	
 	
 	public MyVncClient() {
 		connectionParams = new ParametersHandler.ConnectionParams();
 		settings = ProtocolSettings.getDefaultSettings();
 		uiSettings = super.uiSettings;
+		treeConnectionManager = new TreeConnectionManager(this, isApplet);
 	}
 	
 	public MyVncClient(Parser parser) {
@@ -82,30 +87,25 @@
 			System.exit(0);
 		}
 		MyVncClient myClient = new MyVncClient(parser);
-		if (mainArgs.length != 0) {
-			for (int i = 0; i < argv.length; i++) {
-					myClient.setArgments(mainArgs);
-				// write later
-			}
-		} else {
-			//getHostData();
-		}
-		//SwingUtilities.invokeLater(myClient);
-		myClient.mainLoop();
+		myClient.setType();
+		SwingUtilities.invokeLater(myClient);
+	}
+	
+	public void setType() {
+		super.setType(treeConnectionManager);
 	}
 	
 	public void mainLoop() {
 	//	getHostData();
-		ConnectionManager connectionManager = new ConnectionManager(this, isApplet);
 		if (forceReconnection) {
-			connectionManager.showReconnectDialog("Connection lost", reconnectionReason);
+			treeConnectionManager.showReconnectDialog("Connection lost", reconnectionReason);
 			forceReconnection = false;
 		}
 		tryAgain = true;
 		while (tryAgain) {
 		  connectionParams.hostName = arguments[0];
 		//	workingSocket = connectionManager.connectToTreeHost(connectionParams, settings);
-			workingSocket = connectionManager.connectToTreeHost(connectionParams, settings);
+			workingSocket = treeConnectionManager.connectToHost(connectionParams, settings);
 			if (null == workingSocket) {
 				closeApp();
 				break;
@@ -132,29 +132,29 @@
 				settings.addListener(this);
 				uiSettings.addListener(surface);
 				containerFrame = createContainer();
-				connectionManager.setContainerFrame(containerFrame);
+				treeConnectionManager.setContainerFrame(containerFrame);
 				updateFrameTitle();
 
 				workingProtocol.startNormalHandling(this, surface, clipboardController);
 				tryAgain = false;
 			} catch (UnsupportedProtocolVersionException e) {
-				connectionManager.showReconnectDialog("Unsupported Protocol Version", e.getMessage());
+				treeConnectionManager.showReconnectDialog("Unsupported Protocol Version", e.getMessage());
 				logger.severe(e.getMessage());
 			} catch (UnsupportedSecurityTypeException e) {
-				connectionManager.showReconnectDialog("Unsupported Security Type", e.getMessage());
+				treeConnectionManager.showReconnectDialog("Unsupported Security Type", e.getMessage());
 				logger.severe(e.getMessage());
 			} catch (AuthenticationFailedException e) {
 				passwordFromParams = null;
-				connectionManager.showReconnectDialog("Authentication Failed", e.getMessage());
+				treeConnectionManager.showReconnectDialog("Authentication Failed", e.getMessage());
 				logger.severe(e.getMessage());
 			} catch (TransportException e) {
-				connectionManager.showReconnectDialog("Connection Error", "Connection Error" + ": " + e.getMessage());
+				treeConnectionManager.showReconnectDialog("Connection Error", "Connection Error" + ": " + e.getMessage());
 				logger.severe(e.getMessage());
 			} catch (IOException e) {
-				connectionManager.showReconnectDialog("Connection Error", "Connection Error" + ": " + e.getMessage());
+				treeConnectionManager.showReconnectDialog("Connection Error", "Connection Error" + ": " + e.getMessage());
 				logger.severe(e.getMessage());
 			} catch (FatalException e) {
-				connectionManager.showReconnectDialog("Connection Error", "Connection Error" + ": " + e.getMessage());
+				treeConnectionManager.showReconnectDialog("Connection Error", "Connection Error" + ": " + e.getMessage());
 				logger.severe(e.getMessage());
 			}
 		}
--- /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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/ac/ryukyu/treevnc/server/AcceptThread.java	Tue Aug 21 14:02:05 2012 +0900
@@ -0,0 +1,42 @@
+package ac.ryukyu.treevnc.server;
+import java.net.Socket;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public class AcceptThread implements Runnable {
+        MyRfbProto rfb = null;
+        byte[] imageBytes;
+        int port;
+        
+        AcceptThread(MyRfbProto _rfb) {
+                rfb = _rfb;
+        }
+
+
+        AcceptThread(MyRfbProto _rfb, int p) {
+            rfb = _rfb;
+            port = p;
+        }
+       
+	public void changeRfb(MyRfbProto _rfb) {
+		rfb = _rfb;
+	}
+
+	public void run() {
+		rfb.selectPort(port);
+
+		while (true) {
+			try {
+				Socket newCli = rfb.accept();
+
+				OutputStream os = newCli.getOutputStream();
+				InputStream is = newCli.getInputStream();
+				rfb.newClient(this, newCli, os, is);
+			} catch (IOException e) {
+				e.printStackTrace();
+				System.out.println(e);
+			}
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/ac/ryukyu/treevnc/server/BroadCastProxy.java	Tue Aug 21 14:02:05 2012 +0900
@@ -0,0 +1,40 @@
+package ac.ryukyu.treevnc.server;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.net.Socket;
+
+public class BroadCastProxy {
+	private String str;
+	private Socket socket = null;
+	private PrintStream os = null;
+	private int port = 8182;
+
+	public BroadCastProxy(String _str) {
+		str = _str;
+	}
+
+	void createSocket(String addr) {	
+		while (true) {
+			try {
+				Thread.sleep(1000);
+				socket = new Socket(addr, port);
+				os = new PrintStream(socket.getOutputStream());
+				sendData();
+				os.close();
+				socket.close();
+				break;
+			} catch (IOException e) {
+				System.out.println("Connection faild");
+				continue;
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+
+	void sendData() {
+		os.println(str);
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/ac/ryukyu/treevnc/server/CreateThread.java	Tue Aug 21 14:02:05 2012 +0900
@@ -0,0 +1,88 @@
+package ac.ryukyu.treevnc.server;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import java.net.BindException;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+public class CreateThread implements Runnable {
+	ServerSocket echoServer;
+	AcceptClient acceptClient;
+	int port;
+	
+	public CreateThread(AcceptClient _acc) {
+		acceptClient = _acc;
+		port = 9999;
+	}
+
+	
+	public CreateThread(int port,AcceptClient _acc) {
+		acceptClient = _acc;
+		this.port = port; 
+	}
+	
+
+	void newEchoClient(final BufferedReader is,final PrintStream os) {
+		Runnable echoSender = new Runnable() {
+			public void run() {
+		//		AcceptClient acceptClient = new AcceptClient();
+				// acceptClient new
+				acceptClient.transferParentAddrerss(is,os);
+			}
+		};
+		new Thread(echoSender).start();
+	}
+
+	void selectPort(int p) {
+		int port = p;
+		while (true) {
+			try {
+				initServSock(port);
+				break;
+			} catch (BindException e) {
+				port++;
+				continue;
+			} catch (IOException e) {
+
+			}
+		}
+		System.out.println("accept Echo port = " + port);
+	}
+	
+	void initServSock(int port) throws IOException {
+		echoServer = new ServerSocket(port);
+		this.port = port;
+	}
+	
+	
+	public void run() {
+		selectPort(port);
+		
+		while (true) {
+			try {
+//				echoServer = new ServerSocket(9999);
+				Socket clientSocket = echoServer.accept();
+				BufferedReader is = new BufferedReader(new InputStreamReader(
+						clientSocket.getInputStream()));
+				PrintStream os = new PrintStream(clientSocket.getOutputStream());
+				newEchoClient(is,os);
+//				acceptClient.transferParentAddrerss(is, os);
+			} catch (IOException e) {
+				System.out.println(e);
+			}
+/*
+			try {
+				echoServer.close();
+			} catch (IOException e) {
+				System.out.println(e);
+			}
+*/
+
+		}
+
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/ac/ryukyu/treevnc/server/GetBroadCastProxy.java	Tue Aug 21 14:02:05 2012 +0900
@@ -0,0 +1,98 @@
+package ac.ryukyu.treevnc.server;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.InetAddress;
+import java.net.MulticastSocket;
+import java.net.SocketAddress;
+
+//import TextBoxProxy;
+
+public class GetBroadCastProxy implements Runnable {
+	static final String McastAddr = "224.0.0.1";
+	static final int Port = 8183;
+	static final int BufSize = 1024;
+	private byte[] buf = new byte[BufSize];
+	private byte[] resorve = new byte[BufSize];
+	private ByteArrayInputStream inputStream;
+	private boolean stopFlag = false;
+	private VncProxyService vps;
+	private BroadCastProxy bCast;
+	private String address;
+
+	public GetBroadCastProxy(VncProxyService _vps){
+		vps = _vps;
+		bCast = new BroadCastProxy(vps.rfb.acceptPort+":"+vps.host+":"
+				+vps.rfb.desktopName+":"+vps.acc.getMyAddress()+":");
+	}
+	
+	private synchronized void getData() {
+		try {
+			InetAddress mAddr = InetAddress.getByName(McastAddr);
+			MulticastSocket soc = new MulticastSocket(Port);
+			DatagramPacket recvPacket = new DatagramPacket(buf, BufSize);
+			soc.joinGroup(mAddr);
+			while (true) {
+				soc.receive(recvPacket);
+				address = getAddress(recvPacket.getSocketAddress());
+				inputStream = new ByteArrayInputStream(recvPacket.getData());
+				inputStream.read(resorve);
+				if("who".equals(castString(resorve))){
+						replyBroadCast();
+				}
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	private void replyBroadCast() {
+		Runnable sender = new Runnable() {
+			public void run() {
+				bCast.createSocket(address);
+			}
+		};
+		new Thread(sender).start();
+	}
+
+	private String getAddress(SocketAddress addr) {
+		String str = addr.toString();
+		str = str.substring(1,str.indexOf(":"));
+		return str;
+	}
+/*	
+	private int castBytoToInt(byte[] a) {
+		int value = 0;
+		ByteArrayInputStream bais = new ByteArrayInputStream(a);
+		DataInputStream dis = new DataInputStream(bais);
+		try {
+			value = dis.readInt();
+		} catch (IOException e) {
+		}
+		System.out.println(value);
+		return value;
+	}
+*/
+	private String castString(byte[] a) {
+		String recover = new String(a);
+		recover = recover.replace("¥n", "");
+		recover = recover.trim();
+//		System.out.println(recover);
+		return recover;
+	}
+	
+	
+	public void run() {
+		getData();
+	}
+
+	public void setStopFlag(boolean stopFlag) {
+		this.stopFlag = stopFlag;
+	}
+
+	public boolean isStopFlag() {
+		return stopFlag;
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/ac/ryukyu/treevnc/server/MyRfbProtoProxy.java	Tue Aug 21 14:02:05 2012 +0900
@@ -0,0 +1,663 @@
+package ac.ryukyu.treevnc.server;
+
+import static org.junit.Assert.*;
+
+import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.image.BufferedImage;
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.BindException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.nio.ByteBuffer;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import javax.imageio.ImageIO;
+
+import org.junit.Test;
+
+import ac.ryukyu.treevnc.MulticastQueue;
+
+//import myVncProxy.MulticastQueue.Client;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.zip.DataFormatException;
+import java.util.zip.Deflater;
+import java.util.zip.Inflater;
+import java.io.OutputStream;
+
+public class MyRfbProtoProxy {
+	final static String versionMsg_3_855 = "RFB 003.855\n";
+	/**
+	 * CheckMillis is one of new msgType for RFB 3.855.
+	 */
+	final static byte SpeedCheckMillis = 4;
+
+	// Secyrity type of OS X
+	final static int SecTypeReqAccess = 32;
+
+	// Supported authentication types
+	final static int AuthAccess = 32;
+
+	private static final int INFLATE_BUFSIZE = 1024 * 100;
+	boolean printStatusFlag = false;
+	long startCheckTime;
+	private int messageType;
+	private int rectangles;
+	private int rectX;
+	private int rectY;
+	private int rectW;
+	private int rectH;
+	private int encoding;
+	private int zLen;
+	private boolean clicomp = false;
+
+	private ServerSocket servSock;
+	protected int acceptPort;
+	// private byte initData[];
+	byte initData[];
+	private LinkedList<Socket> cliListTmp;
+	private LinkedList<Socket> cliList;
+	boolean createBimgFlag;
+	boolean proxyFlag = true;
+
+	ExecutorService executor;
+
+	byte[] pngBytes;
+
+	// private MulticastQueue<LinkedList<ByteBuffer>> multicastqueue = new
+	// MostRecentMultiCast<LinkedList<ByteBuffer>>(10);
+	private MulticastQueue<LinkedList<ByteBuffer>> multicastqueue = new MulticastQueue<LinkedList<ByteBuffer>>();
+	private int clients = 0;
+	private Inflater inflater = new Inflater();
+	private Deflater deflater = new Deflater();
+	private CreateThread geth;
+	// private Thread requestThread;
+	private RequestScreenThread rThread;
+	private Thread requestThread;
+
+	public MyRfbProtoProxy() throws IOException {
+	}
+
+
+	void initServSock(int port) throws IOException {
+		servSock = new ServerSocket(port);
+		acceptPort = port;
+	}
+
+	void authenticationRequestAccess() throws IOException {
+
+		byte[] headBuf = new byte[2];
+		is.read(headBuf);
+		if (headBuf[1] == 2) {
+			byte[] b = new byte[258];
+			is.read(b);
+
+			byte[] outBuf = new byte[256];
+			os.write(outBuf);
+			os.flush();
+		} else if (headBuf[1] == 23) {
+			byte[] b = new byte[130];
+			is.read(b);
+			byte[] outBuf = new byte[192];
+			os.write(outBuf);
+			os.flush();
+		}
+
+		int result = readU32();
+		if (result != 0) {
+			System.out.println("faild authentication  ");
+			throw new IOException();
+		}
+
+	}
+
+	/*
+	 * default port number is 5999.
+	 */
+	public void selectPort(int p) {
+		if (servSock != null)
+			return;
+		int port = p;
+		while (true) {
+			try {
+				initServSock(port);
+				break;
+			} catch (BindException e) {
+				port++;
+				continue;
+			} catch (IOException e) {
+
+			}
+		}
+		System.out.println("accept port = " + port);
+	}
+
+	int getAcceptPort() {
+		return acceptPort;
+	}
+
+	void setSoTimeout(int num) throws IOException {
+		servSock.setSoTimeout(num);
+	}
+
+	public Socket accept() throws IOException {
+		return servSock.accept();
+	}
+
+	void addSock(Socket sock) {
+		cliList.add(sock);
+	}
+
+	void addSockTmp(Socket sock) {
+		System.out.println("connected " + sock.getInetAddress());
+		cliListTmp.add(sock);
+	}
+
+	boolean markSupported() {
+		return is.markSupported();
+	}
+
+	synchronized void changeStatusFlag() {
+		printStatusFlag = true;
+	}
+
+	void printMills() {
+		if (printStatusFlag) {
+
+			changeStatusFlag();
+		} else {
+			changeStatusFlag();
+		}
+	}
+
+
+	void requestThreadStart() {
+		requestThread.start();
+	}
+
+	public synchronized void requestThreadNotify() {
+		rThread.reStart();
+	}
+
+	/**
+	 * gzip byte arrays
+	 * 
+	 * @param deflater
+	 * @param inputs
+	 *            byte data[]
+	 * @param inputIndex
+	 * @param outputs
+	 *            byte data[]
+	 * @return byte length in last byte array
+	 * @throws IOException
+	 */
+	public int zip(Deflater deflater, LinkedList<ByteBuffer> inputs,
+			int inputIndex, LinkedList<ByteBuffer> outputs) throws IOException {
+		int len = 0;
+		ByteBuffer c1 = ByteBuffer.allocate(INFLATE_BUFSIZE);
+		while (inputIndex < inputs.size()) {
+			ByteBuffer b1 = inputs.get(inputIndex++);
+			deflater.setInput(b1.array(), b1.position(), b1.remaining());
+			/**
+			 * If we finish() stream and reset() it, Deflater start new gzip
+			 * stream, this makes continuous zlib reader unhappy. if we remove
+			 * finish(), Deflater.deflate() never flushes its output. The
+			 * original zlib deflate has flush flag. I'm pretty sure this a kind
+			 * of bug of Java library.
+			 */
+			if (inputIndex == inputs.size())
+				deflater.finish();
+			int len1 = 0;
+			do {
+				len1 = deflater.deflate(c1.array(), c1.position(),
+						c1.remaining());
+				if (len1 > 0) {
+					len += len1;
+					c1.position(c1.position() + len1);
+					if (c1.remaining() == 0) {
+						c1.flip();
+						outputs.addLast(c1);
+						c1 = ByteBuffer.allocate(INFLATE_BUFSIZE);
+					}
+				}
+			} while (len1 > 0 || !deflater.needsInput()); // &&!deflater.finished());
+		}
+		if (c1.position() != 0) {
+			c1.flip();
+			outputs.addLast(c1);
+		}
+		deflater.reset();
+		return len;
+	}
+
+	/**
+	 * gunzip byte arrays
+	 * 
+	 * @param inflater
+	 * @param inputs
+	 *            byte data[]
+	 * @param outputs
+	 *            byte data[]
+	 * @return number of total bytes
+	 * @throws IOException
+	 */
+	public int unzip(Inflater inflater, LinkedList<ByteBuffer> inputs,
+			int inputIndex, LinkedList<ByteBuffer> outputs, int bufSize)
+			throws DataFormatException {
+		int len = 0;
+		ByteBuffer buf = ByteBuffer.allocate(bufSize);
+		while (inputIndex < inputs.size()) {
+			ByteBuffer input = inputs.get(inputIndex++);
+			inflater.setInput(input.array(), input.position(), input.limit());
+			// if (inputIndex==inputs.size()) if inflater/deflater has symmetry,
+			// we need this
+			// inflater.end(); but this won't work
+			do {
+				int len0 = inflater.inflate(buf.array(), buf.position(),
+						buf.remaining());
+				if (len0 > 0) {
+					buf.position(buf.position() + len0);
+					len += len0;
+					if (buf.remaining() == 0) {
+						buf.flip();
+						outputs.addLast(buf);
+						buf = ByteBuffer.allocate(bufSize);
+					}
+				}
+			} while (!inflater.needsInput());
+		}
+		if (buf.position() != 0) {
+			buf.flip();
+			outputs.addLast(buf);
+		}
+		return len;
+	}
+
+	float maxMag = 1;
+
+	/**
+	 * send data to clients
+	 * 
+	 * @param dataLen
+	 * @throws IOException
+	 * @throws DataFormatException
+	 * 
+	 *             Zlibed packet is compressed in context dependent way, that
+	 *             is, it have to send from the beginning. But this is
+	 *             impossible. So we have to compress it again for each clients.
+	 *             Separate deflater for each clients is necessary.
+	 * 
+	 *             Java's deflater does not support flush. This means to get the
+	 *             result, we have to finish the compression. Reseting start new
+	 *             compression, but it is not accepted well in zlib continuous
+	 *             reading. So we need new Encoding ZRLEE which reset decoder
+	 *             for each packet. ZRLEE can be invisible from user, but it
+	 *             have to be implemented in the clients. ZRLEE compression is
+	 *             not context dependent, so no recompression is necessary.
+	 */
+
+	void readSendData(int dataLen) throws IOException, DataFormatException {
+		LinkedList<ByteBuffer> bufs = new LinkedList<ByteBuffer>();
+		ByteBuffer header = ByteBuffer.allocate(16);
+		readFully(header.array(), 0, 16);
+		header.limit(16);
+		if (header.get(0) == RfbProto.FramebufferUpdate) {
+			int encoding = header.getInt(12);
+			if (encoding == RfbProto.EncodingZRLE
+					|| encoding == RfbProto.EncodingZlib) { // ZRLEE is already
+															// recompressed
+				ByteBuffer len = ByteBuffer.allocate(4);
+				readFully(len.array(), 0, 4);
+				len.limit(4);
+				ByteBuffer inputData = ByteBuffer.allocate(dataLen - 20);
+
+				startTiming();
+				readFully(inputData.array(), 0, inputData.capacity());
+//				System.out.println(dataLen);
+				inputData.limit(dataLen - 20);
+				stopTiming();
+
+				LinkedList<ByteBuffer> inputs = new LinkedList<ByteBuffer>();
+				inputs.add(inputData);
+
+				header.putInt(12, RfbProto.EncodingZRLEE); // means recompress
+															// every time
+				// using new Deflecter every time is incompatible with the
+				// protocol, clients have to be modified.
+				Deflater nDeflater = deflater; // new Deflater();
+				LinkedList<ByteBuffer> out = new LinkedList<ByteBuffer>();
+				unzip(inflater, inputs, 0, out, INFLATE_BUFSIZE);
+				// dump32(inputs);
+				int len2 = zip(nDeflater, out, 0, bufs);
+				ByteBuffer blen = ByteBuffer.allocate(4);
+				blen.putInt(len2);
+				blen.flip();
+				bufs.addFirst(blen);
+
+				bufs.addFirst(header);
+			//	if(dataLen<=64000)
+					multicastqueue.put(bufs);
+				// is.reset();
+
+				/*
+				 * System.out.println("ZRLE = "+dataLen);
+				 * System.out.println("ZRLEE = "+(len2+20)); float mag =
+				 * (float)dataLen / (float)(len2 + 20);
+				 * System.out.println("ZRLE / ZRLEE = "+ mag); if(mag > maxMag)
+				 * maxMag = mag; System.out.println("maxMag = "+maxMag);
+				 */
+				return;
+			}
+			bufs.add(header);
+			if (dataLen > 16) {
+				ByteBuffer b = ByteBuffer.allocate(dataLen - 16);
+				startTiming();
+				readFully(b.array(), 0, dataLen - 16);
+				b.limit(dataLen - 16);
+				stopTiming();
+				bufs.add(b);
+			}
+			multicastqueue.put(bufs);
+			// is.reset();
+			return;
+		}
+		is.reset();
+
+		// It may be compressed. We can inflate here to avoid repeating clients
+		// decompressing here,
+		// but it may generate too many large data. It is better to do it in
+		// each client.
+		// But we have do inflation for all input data, so we have to do it
+		// here.
+	}
+
+	public void newClient(AcceptThread acceptThread, final Socket newCli,
+			final OutputStream os, final InputStream is) throws IOException {
+		// createBimgFlag = true;
+		// rfb.addSockTmp(newCli);
+		// addSock(newCli);
+		final int myId = clients;
+		final MulticastQueue.Client<LinkedList<ByteBuffer>> c = multicastqueue
+				.newClient();
+		final AtomicInteger writerRunning = new AtomicInteger();
+		writerRunning.set(1);
+		/**
+		 * Timeout thread. If a client is suspended, it has top of queue
+		 * indefinitely, which caused memory overflow. After the timeout, we
+		 * poll the queue and discard it. Start long wait if writer is running.
+		 */
+		final Runnable timer = new Runnable() {
+			public void run() {
+				int count = 0;
+				for (;;) {
+					long timeout = 50000 / 8;
+					try {
+						synchronized (this) {
+							int state, flag;
+							writerRunning.set(0);
+							wait(timeout);
+							flag = 0;
+							while ((state = writerRunning.get()) == 0) {
+								c.poll(); // discard, should be timeout
+								count++;
+								if (flag == 0) {
+									System.out.println("Discarding " + myId
+											+ " count=" + count);
+									flag = 1;
+								}
+								wait(10); // if this is too short, writer cannot
+											// take the poll, if this is too
+											// long, memory will overflow...
+							}
+							if (flag == 1)
+								System.out.println("Resuming " + myId
+										+ " count=" + count);
+							if (state != 1) {
+								System.out.println("Client died " + myId);
+								break;
+							}
+						}
+					} catch (InterruptedException e) {
+					}
+				}
+			}
+		};
+		new Thread(timer).start();
+		/**
+		 * discard all incoming from clients
+		 */
+		final Runnable reader = new Runnable() {
+			public void run() {
+				byte b[] = new byte[4096];
+				for (;;) {
+					try {
+						int c = is.read(b);
+						if (c <= 0)
+							throw new IOException();
+						// System.out.println("client read "+c);
+					} catch (IOException e) {
+						try {
+							writerRunning.set(2);
+							os.close();
+							is.close();
+						} catch (IOException e1) {
+						}
+						return;
+					}
+				}
+			}
+		};
+		/**
+		 * send packets to a client
+		 */
+		Runnable sender = new Runnable() {
+			public void run() {
+				writerRunning.set(1);
+				try {
+					requestThreadNotify();
+					// rThread.checkDelay();
+
+					/**
+					 * initial connection of RFB protocol
+					 */
+					sendRfbVersion(os);
+					// readVersionMsg(is);
+					int rfbMinor = readVersionMsg(is, os);
+					sendSecurityType(os);
+					readSecType(is);
+					sendSecResult(os);
+					readClientInit(is);
+					sendInitData(os);
+					new Thread(reader).start(); // discard incoming packet here
+												// after.
+					// writeFramebufferUpdateRequest(0,0, framebufferWidth,
+					// framebufferHeight, false );
+					int i  = 0;
+					for (;;) {
+						LinkedList<ByteBuffer> bufs = c.poll();
+						int inputIndex = 0;
+						ByteBuffer header = bufs.get(inputIndex);
+						if (header == null)
+							continue;
+						else if (header.get(0) == RfbProto.CheckDelay) {
+							writeToClient(os, bufs, inputIndex);
+							continue;
+						} else if (header.get(0) == RfbProto.FramebufferUpdate) {
+							// System.out.println("client "+ myId);
+						}
+						/*
+						if(i%20==0){
+							sendDataCheckDelay();
+						}
+						i++;
+						*/
+						writeToClient(os, bufs, inputIndex);
+						writerRunning.set(1); // yes my client is awaking.
+					}
+				} catch (IOException e) {
+					try {
+						writerRunning.set(2);
+						os.close();
+					} catch (IOException e1) {
+					}
+					/* if socket closed cliList.remove(newCli); */
+				}
+			}
+
+			public void writeToClient(final OutputStream os,
+					LinkedList<ByteBuffer> bufs, int inputIndex)
+					throws IOException {
+				while (inputIndex < bufs.size()) {
+					ByteBuffer b = bufs.get(inputIndex++);
+					os.write(b.array(), b.position(), b.limit());
+				}
+				os.flush();
+			}
+		};
+		clients++;
+		new Thread(sender).start();
+
+	}
+
+	public void dump32(LinkedList<ByteBuffer> bufs) {
+		int len = 0;
+		for (ByteBuffer b : bufs)
+			len += b.remaining();
+		ByteBuffer top = bufs.getFirst();
+		ByteBuffer end = bufs.getLast();
+		System.err.println("length: " + len);
+		System.err.print("head 0: ");
+		for (int i = 0; i < 16 && i < top.remaining(); i++) {
+			System.err.print(" " + top.get(i));
+		}
+		System.err.print("tail 0: ");
+		for (int i = 0; i < 16 && i < end.remaining(); i++) {
+			System.err.print(" " + end.get(i));
+		}
+		System.err.println();
+	}
+
+	@Test
+	public void test1() {
+		try {
+			LinkedList<ByteBuffer> in = new LinkedList<ByteBuffer>();
+			LinkedList<ByteBuffer> out = new LinkedList<ByteBuffer>();
+			LinkedList<ByteBuffer> out2 = new LinkedList<ByteBuffer>();
+			// if (false) {
+			// for(int i=0;i<10;i++) {
+			// in.add(ByteBuffer.wrap("test1".getBytes()));
+			// in.add(ByteBuffer.wrap("test2".getBytes()));
+			// in.add(ByteBuffer.wrap("test3".getBytes()));
+			// in.add(ByteBuffer.wrap("test44".getBytes()));
+			// }
+			// } else
+			{
+				String t = "";
+				for (int i = 0; i < 10; i++) {
+					t += "test1";
+					t += "test2";
+					t += "test3";
+					t += "test44";
+				}
+				in.add(ByteBuffer.wrap(t.getBytes()));
+			}
+
+			LinkedList<ByteBuffer> in1 = clone(in);
+
+			Deflater deflater = new Deflater();
+			zip(deflater, in, 0, out);
+			// LinkedList<ByteBuffer> out3 = clone(out); zipped result is depend
+			// on deflator's state
+			unzip(inflater, out, 0, out2, INFLATE_BUFSIZE);
+			// inflater.reset();
+			equalByteBuffers(in1, out2);
+			LinkedList<ByteBuffer> out4 = new LinkedList<ByteBuffer>();
+			deflater = new Deflater();
+			zip(deflater, out2, 0, out4);
+			LinkedList<ByteBuffer> out5 = new LinkedList<ByteBuffer>();
+			unzip(inflater, out4, 0, out5, INFLATE_BUFSIZE);
+			int len = equalByteBuffers(in1, out5);
+
+			System.out.println("Test Ok. " + len);
+		} catch (Exception e) {
+			assertEquals(0, 1);
+		}
+	}
+
+	private LinkedList<ByteBuffer> clone(LinkedList<ByteBuffer> in) {
+		LinkedList<ByteBuffer> copy = new LinkedList<ByteBuffer>();
+		for (ByteBuffer b : in) {
+			ByteBuffer c = b.duplicate();
+			copy.add(c);
+		}
+		return copy;
+	}
+
+	public int equalByteBuffers(LinkedList<ByteBuffer> in,
+			LinkedList<ByteBuffer> out2) {
+		int len = 0;
+		Iterable<Byte> i = byteBufferIterator(in);
+		Iterator<Byte> o = byteBufferIterator(out2).iterator();
+
+		for (int b : i) {
+			len++;
+			if (o.hasNext()) {
+				int c = o.next();
+				assertEquals(b, c);
+			} else
+				assertEquals(0, 1);
+		}
+		if (o.hasNext())
+			assertEquals(0, 1);
+		// System.out.println();
+		return len;
+	}
+
+	private Iterable<Byte> byteBufferIterator(final LinkedList<ByteBuffer> in) {
+		return new Iterable<Byte>() {
+			public Iterator<Byte> iterator() {
+				return new Iterator<Byte>() {
+					int bytes = 0;
+					int buffers = 0;
+
+					public boolean hasNext() {
+						for (;;) {
+							if (buffers >= in.size())
+								return false;
+							ByteBuffer b = in.get(buffers);
+							if (!(bytes < b.remaining())) {
+								buffers++;
+								bytes = 0;
+							} else
+								return true;
+						}
+					}
+
+					public Byte next() {
+						ByteBuffer bf = in.get(buffers);
+						byte b = bf.get(bytes++);
+						if (bf.remaining() <= bytes) {
+							buffers++;
+							bytes = 0;
+						}
+						// System.out.print(b);
+						return b;
+					}
+
+					public void remove() {
+					}
+				};
+			}
+		};
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/ac/ryukyu/treevnc/server/RequestScreenThread.java	Tue Aug 21 14:02:05 2012 +0900
@@ -0,0 +1,43 @@
+package ac.ryukyu.treevnc.server;
+
+import java.io.IOException;
+
+public class RequestScreenThread implements Runnable {
+	MyRfbProtoProxy rfb;
+
+	RequestScreenThread(MyRfbProtoProxy _rfb) {
+		rfb = _rfb;
+	}
+
+	public void run() {
+		while (true) {
+			try {
+				waitThread();
+				Thread.sleep(3000);
+				rfb.writeFramebufferUpdateRequest(0, 0, rfb.framebufferWidth,
+						rfb.framebufferHeight, false);
+
+			} catch (Exception e) {
+				e.printStackTrace();
+				break;
+			}
+		}
+	}
+	
+    public synchronized void waitThread() {
+    	try{
+    		wait();
+        }catch(InterruptedException e) {
+        	e.printStackTrace();
+    	}
+    }
+
+    public synchronized void reStart() {
+    	notify();
+    }
+    
+    public void checkDelay() throws IOException {
+    	rfb.checkDelayData();
+    }
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/ac/ryukyu/treevnc/server/TextBoxProxy.java	Tue Aug 21 14:02:05 2012 +0900
@@ -0,0 +1,126 @@
+package ac.ryukyu.treevnc.server;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+
+public class TextBoxProxy extends JFrame implements ActionListener {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	private JPanel panel;
+	private JButton button;
+	private JButton button1;
+	private TextField t1;
+	private TextField t2;
+	private JPasswordField pw;
+	private double width;
+	private double height;
+	private JLabel label;
+	private boolean flag;
+	private VncProxyService vps;
+
+	public void ipRegister() {
+		setSize();
+		setText();
+		visible();
+	}
+
+	public TextBoxProxy(VncProxyService _vps) {
+		vps = _vps;
+		setTitle("Informatin Connection Address");
+		setResizable(false);
+		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+	}
+
+	private void setSize() {
+		Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
+		width = (d.getWidth() / 2);
+		height = (d.getHeight() / 2);
+	}
+
+	private void visible() {
+		Point point = new Point();
+		point.setLocation(width - 250, height - 80);
+		setLocation(point.getLocation());
+		pack();
+		setVisible(true);
+	}
+	
+	private void init(){
+		frameInit();
+//		panel = null;
+//		button = null;
+//		label = null;
+		setVisible(false);
+	}
+	
+	public void changeHost() {
+		init();
+		button1 = new JButton("Change Host");
+		t1 = new TextField("Address", 30);
+		panel = new JPanel();
+		panel.add(t1);
+		panel.add(button1);
+		button1.addActionListener(this);
+		label = new JLabel();
+		Container contentPane = getContentPane();
+		contentPane.add(panel, BorderLayout.CENTER);
+		contentPane.add(label, BorderLayout.SOUTH);
+		visible();
+	}
+
+	private void setText() {
+		panel = new JPanel();
+		t1 = new TextField("localhost", 30);
+		t2 = new TextField("5900", 5);
+//		pw = new JPasswordField("Password",30);
+		button = new JButton("Connect");
+		panel.add(t1);
+		panel.add(t2);
+//		panel.add(pw);
+		panel.add(button);
+		button.addActionListener(this);
+		label = new JLabel();
+		Container contentPane = getContentPane();
+		contentPane.add(panel, BorderLayout.CENTER);
+		contentPane.add(label, BorderLayout.SOUTH);
+	}
+	
+	public String getAddress() {
+		while(!(flag)) {
+			try {
+				Thread.sleep(500);
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+		}
+		return t1.getText();
+	}
+	public String getPort() {
+		return t2.getText();
+	}
+	
+
+	public String getPassword() {
+		return String.valueOf(pw.getPassword());
+	}
+
+
+	public void actionPerformed(ActionEvent e) {
+		if(e.getSource()==button) {
+			flag = true;
+			setVisible(false);
+		}
+		if(e.getSource()==button1)
+			try {
+				init();
+				vps.host = getAddress();
+				vps.changeInit();
+			} catch (Exception e1) {
+				e1.printStackTrace();
+			}
+	}
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/ac/ryukyu/treevnc/server/VncProxyService.java	Tue Aug 21 14:02:05 2012 +0900
@@ -0,0 +1,179 @@
+package ac.ryukyu.treevnc.server;
+
+import java.awt.event.*;
+import java.io.*;
+import java.util.logging.Logger;
+
+
+import com.glavsoft.exceptions.AuthenticationFailedException;
+import com.glavsoft.exceptions.FatalException;
+import com.glavsoft.exceptions.TransportException;
+import com.glavsoft.exceptions.UnsupportedProtocolVersionException;
+import com.glavsoft.exceptions.UnsupportedSecurityTypeException;
+import com.glavsoft.rfb.IChangeSettingsListener;
+import com.glavsoft.rfb.IRfbSessionListener;
+import com.glavsoft.rfb.protocol.Protocol;
+import com.glavsoft.rfb.protocol.ProtocolSettings;
+import com.glavsoft.transport.Reader;
+import com.glavsoft.transport.Writer;
+import com.glavsoft.viewer.ConnectionManager;
+import com.glavsoft.viewer.Viewer;
+import com.glavsoft.viewer.cli.Parser;
+import com.glavsoft.viewer.swing.ClipboardControllerImpl;
+import com.glavsoft.viewer.swing.ParametersHandler;
+import com.glavsoft.viewer.swing.Surface;
+import com.glavsoft.viewer.swing.UiSettings;
+import com.glavsoft.viewer.swing.ParametersHandler.ConnectionParams;
+
+public class VncProxyService extends Viewer implements Runnable, 
+	IRfbSessionListener, IChangeSettingsListener {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+
+
+	public VncProxyService(Parser parser) {
+		this();
+		ParametersHandler.completeSettingsFromCLI(parser, connectionParams, settings, uiSettings);
+		showControls = ParametersHandler.showControls;
+		passwordFromParams = parser.getValueFor(ParametersHandler.ARG_PASSWORD);
+		logger.info("TightVNC Viewer version " + ver());
+		isApplet = false;
+	}
+	
+	public VncProxyService() {
+		connectionParams = new ParametersHandler.ConnectionParams();
+		settings = ProtocolSettings.getDefaultSettings();
+		uiSettings = super.uiSettings;
+
+	}
+	
+	boolean isClient = false;
+	public static final int DEFAULT_PORT = 5900;
+	public static Logger logger = Logger.getLogger("com.glavsoft");
+	private boolean forceReconnection;
+	private String reconnectionReason;
+	private ConnectionParams connectionParams;
+	private final ProtocolSettings settings;
+	private final UiSettings uiSettings;
+	private String[] arguments;
+	
+	
+	public static void main(String[] argv) {
+		String[] mainArgs = argv;
+		System.out.println(mainArgs.length);
+		// input into arguments Decision
+
+		Parser parser = new Parser();
+		ParametersHandler.completeParserOptions(parser);
+
+		parser.parse(argv);
+		if (parser.isSet(ParametersHandler.ARG_HELP)) {
+			printUsage(parser.optionsUsage());
+			System.exit(0);
+		}
+		VncProxyService vps = new VncProxyService(parser);
+		if (mainArgs.length != 0) {
+			for (int i = 0; i < argv.length; i++) {
+				vps.setArguments(mainArgs);
+				// write later
+			}
+		} else {
+			//getHostData();
+		}
+		//SwingUtilities.invokeLater(myClient);
+		Thread th = new Thread(vps);
+		th.start();
+	}
+	
+	private void setArguments(String[] mainArgs) {
+		arguments = mainArgs;		
+	}
+
+	@Override
+	public void run() {
+	//	getHostData();
+		ConnectionManager connectionManager = new ConnectionManager(this, isApplet);
+		if (forceReconnection) {
+			connectionManager.showReconnectDialog("Connection lost", reconnectionReason);
+			forceReconnection = false;
+		}
+		tryAgain = true;
+		while (tryAgain) {
+		  connectionParams.hostName = arguments[0];
+		//	workingSocket = connectionManager.connectToTreeHost(connectionParams, settings);
+			workingSocket = connectionManager.connectToTreeHost(connectionParams, settings);
+			if (null == workingSocket) {
+				closeApp();
+				break;
+			}
+			logger.info("Connected");
+
+			try {
+				workingSocket.setTcpNoDelay(true); // disable Nagle algorithm
+				Reader reader = new Reader(workingSocket.getInputStream());
+				Writer writer = new Writer(workingSocket.getOutputStream());
+				
+				workingProtocol = new Protocol(reader, writer,
+						new PasswordChooser(passwordFromParams, connectionParams, containerFrame, this),
+						settings);
+
+				workingProtocol.handshake();
+				// input into change parents
+                ClipboardControllerImpl clipboardController =
+		                new ClipboardControllerImpl(workingProtocol, settings.getRemoteCharsetName());
+				clipboardController.setEnabled(settings.isAllowClipboardTransfer());
+				settings.addListener(clipboardController);
+
+				surface = new Surface(workingProtocol, this, uiSettings.getScaleFactor());
+				settings.addListener(this);
+				uiSettings.addListener(surface);
+				containerFrame = createContainer();
+				connectionManager.setContainerFrame(containerFrame);
+				updateFrameTitle();
+
+				workingProtocol.startNormalHandling(this, surface, clipboardController);
+				tryAgain = false;
+			} catch (UnsupportedProtocolVersionException e) {
+				connectionManager.showReconnectDialog("Unsupported Protocol Version", e.getMessage());
+				logger.severe(e.getMessage());
+			} catch (UnsupportedSecurityTypeException e) {
+				connectionManager.showReconnectDialog("Unsupported Security Type", e.getMessage());
+				logger.severe(e.getMessage());
+			} catch (AuthenticationFailedException e) {
+				passwordFromParams = null;
+				connectionManager.showReconnectDialog("Authentication Failed", e.getMessage());
+				logger.severe(e.getMessage());
+			} catch (TransportException e) {
+				connectionManager.showReconnectDialog("Connection Error", "Connection Error" + ": " + e.getMessage());
+				logger.severe(e.getMessage());
+			} catch (IOException e) {
+				connectionManager.showReconnectDialog("Connection Error", "Connection Error" + ": " + e.getMessage());
+				logger.severe(e.getMessage());
+			} catch (FatalException e) {
+				connectionManager.showReconnectDialog("Connection Error", "Connection Error" + ": " + e.getMessage());
+				logger.severe(e.getMessage());
+			}
+		}
+
+	}
+
+
+
+	@Override
+	public void destroy() {
+
+	}
+
+	
+
+	@Override
+	public void windowClosing(WindowEvent e) {
+		if (e != null && e.getComponent() != null) {
+			e.getWindow().setVisible(false);
+		}
+		closeApp();
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/jp/ac/u_ryukyu/treevnc/test/ThreadTest.java	Tue Aug 21 14:02:05 2012 +0900
@@ -0,0 +1,19 @@
+package jp.ac.u_ryukyu.treevnc.test;
+
+public class ThreadTest {
+	// exit(0) forces other threads 
+	// if there is no exit(0), main routine wait to join other threads implicitly.  
+	public static void main(String[] args) {
+		Thread th = new Thread(new Runnable(){
+			@Override
+			public void run() {
+				for(int i = 0;i < 10; ) {
+					
+				}				
+			}
+		
+		});
+		th.start();
+		System.exit(0);
+	}
+}
--- a/src/viewer_swing/java/com/glavsoft/viewer/ConnectionManager.java	Wed Aug 15 17:08:10 2012 +0900
+++ b/src/viewer_swing/java/com/glavsoft/viewer/ConnectionManager.java	Tue Aug 21 14:02:05 2012 +0900
@@ -79,6 +79,7 @@
 		}
 	}
 	
+/*	
 	public Socket connectToTreeHost(final ParametersHandler.ConnectionParams connectionParams, ProtocolSettings settings) {
 		Socket socket = null;
 		boolean wasError = false;
@@ -117,7 +118,7 @@
 			}
 		return socket;
 	}
-	
+*/
 
 	public Socket connectToHost(final ParametersHandler.ConnectionParams connectionParams, ProtocolSettings settings) {
 		Socket socket = null;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/viewer_swing/java/com/glavsoft/viewer/TreeConnectionManager.java	Tue Aug 21 14:02:05 2012 +0900
@@ -0,0 +1,67 @@
+package com.glavsoft.viewer;
+
+import java.awt.event.WindowListener;
+import java.io.IOException;
+import java.net.Socket;
+import java.net.UnknownHostException;
+
+import ac.ryukyu.treevnc.client.GetDataClient;
+import ac.ryukyu.treevnc.client.GetHostClient;
+
+import com.glavsoft.rfb.protocol.ProtocolSettings;
+import com.glavsoft.viewer.swing.ParametersHandler;
+
+public class TreeConnectionManager extends ConnectionManager {
+	
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	public TreeConnectionManager(WindowListener appWindowListener,
+			boolean isApplet) {
+		super(appWindowListener, isApplet);
+	}
+	
+	@Override
+	public Socket connectToHost(final ParametersHandler.ConnectionParams connectionParams, ProtocolSettings settings) {
+		Socket socket = null;
+		boolean wasError = false;
+		GetHostClient bCast = new GetHostClient("who");
+		bCast.createSocket();
+		bCast.sendData();
+		GetDataClient getBcast = new GetDataClient();
+		Thread runBcast = new Thread(getBcast);
+		runBcast.start();
+		getBcast.setStopFlag(true);
+		//connectionParams.hostName = getBcast.textAddress();
+		if("notFound".equals(connectionParams.hostName)) {
+			getBcast.text.ipRegister();
+			connectionParams.hostName = getBcast.textAddress();
+			connectionParams.portNumber = Integer.parseInt(getBcast.textPort());
+			//connectionParams.portNumber = 5900;
+		} else {
+			// connectionParams.portNumber = Integer.parseInt(getBcast.textPort());
+			connectionParams.portNumber = 5900;
+		}
+			Viewer.logger.info("Connecting to host " + connectionParams.hostName + ":" + connectionParams.portNumber);
+			try {
+				socket = new Socket(connectionParams.hostName, connectionParams.portNumber);
+				wasError = false;
+			} catch (UnknownHostException e) {
+				Viewer.logger.severe("Unknown host: " + connectionParams.hostName);
+				showConnectionErrorDialog("Unknown host: '" + connectionParams.hostName + "'");
+				wasError = true;
+			} catch (IOException e) {
+				Viewer.logger.severe("Couldn't connect to: " +
+						connectionParams.hostName + ":" + connectionParams.portNumber +
+						": " + e.getMessage());
+				showConnectionErrorDialog("Couldn't connect to: '" + connectionParams.hostName +
+						"'\n" + e.getMessage());
+				wasError = true;
+			}
+		return socket;
+	}
+	
+
+
+}
--- a/src/viewer_swing/java/com/glavsoft/viewer/Viewer.java	Wed Aug 15 17:08:10 2012 +0900
+++ b/src/viewer_swing/java/com/glavsoft/viewer/Viewer.java	Tue Aug 21 14:02:05 2012 +0900
@@ -66,6 +66,7 @@
 	protected boolean forceReconnection;
 	protected String reconnectionReason;
 	private ContainerManager containerManager;
+	protected ConnectionManager connectionManager;
 
 	public Protocol getWorkingProtocol() {
 		return workingProtocol;
@@ -86,6 +87,10 @@
 	public void setZoomToFitSelected(boolean zoomToFitSelected) {
 		isZoomToFitSelected = zoomToFitSelected;
 	}
+	
+	public void setType(ConnectionManager _connectionManager) {
+		connectionManager = _connectionManager;
+	}
 
 	/**
 	 * Ask user for password if needed
@@ -166,6 +171,7 @@
 		connectionParams = new ParametersHandler.ConnectionParams();
 		settings = ProtocolSettings.getDefaultSettings();
 		uiSettings = new UiSettings();
+		connectionManager = new ConnectionManager(this, isApplet);
 	}
 
 	private Viewer(Parser parser) {
@@ -258,7 +264,6 @@
 		isSeparateFrame = ParametersHandler.isSeparateFrame;
 		passwordFromParams = getParameter(ParametersHandler.ARG_PASSWORD);
 		isApplet = true;
-
 		repaint();
 		SwingUtilities.invokeLater(this);
 	}
@@ -271,7 +276,6 @@
 
 	@Override
 	public void run() {
-		ConnectionManager connectionManager = new ConnectionManager(this, isApplet);
 
 		if (forceReconnection) {
 			connectionManager.showReconnectDialog("Connection lost", reconnectionReason);