view src/main/java/jp/ac/u_ryukyu/treevnc/server/GetBroadCastProxy.java @ 126:775ce6a14f89

find root.
author oc
date Fri, 06 Jun 2014 19:17:32 +0900
parents 40d400a7ec84
children
line wrap: on
line source

package jp.ac.u_ryukyu.treevnc.server;

import java.io.IOException;
import java.io.PrintStream;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;

import jp.ac.u_ryukyu.treevnc.client.TreeVncProtocol;

import com.glavsoft.rfb.protocol.ProtocolContext;
import com.glavsoft.viewer.swing.ConnectionParams;

//import TextBoxProxy;

public class GetBroadCastProxy implements Runnable {
	public static final String McastAddr = "224.0.0.1";
	static final int BufSize = 1024;
	private boolean stopFlag = false;
	private VncProxyService vps;
	public static String MULTICAST_FIND_TREEVNC_ROOT = "TREEVNC-who:";
	private MulticastSocket soc;
    private String bCast;

	public GetBroadCastProxy(VncProxyService _vps,String desktopName,String host){
	    String myaddress = getMyAddress();
	    // getMyAddress is not always connectable eg. in private segment.
		vps = _vps;
		bCast = vps.getRfb().getAcceptPort()+":"+host+":"
				+desktopName+":"+myaddress+":";
	}
	
	/**
	 * To find TreeVNC root, a client sends me a multicast, reply our address to him.
	 *  It contains a port to receive, so multiple TREEVNC clients can run on a PC. 
	 */
	private void replyToRootSearchMulticast() {
		byte[] buf = new byte[BufSize];
		try {
			InetAddress mAddr = InetAddress.getByName(McastAddr);
			soc = new MulticastSocket(ConnectionParams.DEFAULT_VNC_ROOT_FINDER);
			DatagramPacket recvPacket = new DatagramPacket(buf, BufSize);
			soc.joinGroup(mAddr);
			while (!stopFlag) {
				soc.receive(recvPacket);
//				String address = getAddress(recvPacket.getSocketAddress());
		        byte[] reply = recvPacket.getData();
				int len = recvPacket.getLength();
				if (len != 12) {
					continue;
				}
				if ((reply[0]&0xff) != ProtocolContext.FIND_ROOT) {
					continue;
				}
				int port = 0;
				port = reply[8];
				port = port * 256 + reply[9];
				port = port * 256 + reply[10];
				port = port * 256 + reply[11];
				
				TreeVncProtocol t = new TreeVncProtocol("", port);
				try {
					t.findRootReply(getMyAddress(), vps.getRfb().getAcceptPort());
				} catch (IOException e) {
					e.printStackTrace();
				}
				if(stopFlag) break;
			}
		} catch (Exception e) {
			
		}
	}
	
	public int parse_code( byte[] bs,int offset,int len )
	{
	    int intval = 0;
	    for( int i = offset; i < len ; i++ ) {
	        if  (bs[i]==0 ) return intval;
	        intval = intval * 10 + ( bs[ i ] - '0' );
	    }
	    return intval;
	}
	

    /**
     * To find me (TreeVNC root) ,a client send a broadcast with port number.
     * Send  the parameter to connect to him.
     * The client's GetDataClient will receive this message.
     * 
     * @param addr
     * @param port
     * @param str 
     */
	private void replyToClient(String addr, int port_,String str_) {
	    final String address = addr;
	    final int port = port_;
	    final String str = str_;

		TreeVncProtocol t = new TreeVncProtocol("", port_);
		try {
			t.findRootReply(str_, port_);
		} catch (IOException e) {
			e.printStackTrace();
		}
	    
	    Runnable sender = new Runnable() {
			public void run() {
			        try {
			            Thread.sleep(1000);
			            Socket socket = new Socket(address, port);  // This is a TCP stream to reply
			            PrintStream os = new PrintStream(socket.getOutputStream());
			            os.println(str);
			            os.print(Integer.toString(port));
			            os.close();
			            socket.close();
			        } catch (IOException e) {
			            System.out.println("Connection faild");
			        } catch (InterruptedException e) {
			            System.out.println("Connection faild");
			        }
			}
		};
		
		new Thread(sender).start();
	}

	private String getAddress(SocketAddress addr) {
		String str = addr.toString();
		str = str.substring(1,str.indexOf(":"));
		return str;
	}
	
	public void run() {
		replyToRootSearchMulticast();
	}

	public void setStopFlag(boolean stopFlag) {
		this.stopFlag = stopFlag;
	}

	public boolean isStopFlag() {
		return stopFlag;
	}
	
	/**
	 *  getLocalHost() returns hostname's address. It may not connectable, but
	 *  it gives readable hostname. Do not use it to connect.
	 * @return
	 */
	String getMyAddress () {
		InetAddress addr = null;
		try {
			addr = InetAddress.getLocalHost();
		} catch (UnknownHostException e) {
			return "localhost";
		}
		return addr.getHostAddress();
	}
}