view src/main/java/jp/ac/u_ryukyu/treevnc/TreeRootFinderListener.java @ 434:aad75cd6d9e2

Multicast joins both ipv4 and ipv6 now.
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sat, 11 Jun 2016 22:42:58 +0900
parents 42fcc9419498
children 4ac83ab4be81
line wrap: on
line source

package jp.ac.u_ryukyu.treevnc;

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

import java.io.IOException;
import java.net.*;

public class TreeRootFinderListener implements Runnable {
    public static final String Ipv4McastAddr = "224.0.0.1";
    public static final String Ipv6McastAddr = "ff02::1";
    public static String McastAddr = Ipv4McastAddr;

	static final int BufSize = 1024;
	private boolean stopFlag = false;
	private ViewerInterface vps;
	private MulticastSocket soc;
	private SecurityManager securityManager;

	public TreeRootFinderListener(ViewerInterface vncProxyService) {
		vps = vncProxyService;
	}

    public static MulticastSocket createMulticastSocket() throws IOException {
        MulticastSocket soc = new MulticastSocket(ConnectionParams.DEFAULT_VNC_ROOT_FINDER);
		try {
			soc.joinGroup(InetAddress.getByName(McastAddr));
		} catch (SocketException e) {
			System.out.println("join to " +  Ipv4McastAddr + " failed.");
		}
		try {
			soc.joinGroup(InetAddress.getByName(Ipv6McastAddr));
		} catch (SocketException e) {
			System.out.println("join to " +  Ipv6McastAddr + " failed.");
		}
        return soc;
    }

    /**
	 * 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 {
            soc = createMulticastSocket();
			System.out.println("FindRoot listening on "+ InetAddress.getByName(McastAddr));

            DatagramPacket recvPacket = new DatagramPacket(buf, BufSize);
            while (!stopFlag) {
				soc.receive(recvPacket);
				String hostname = recvPacket.getAddress().getHostAddress();
		        byte[] reply = recvPacket.getData();
				int len = recvPacket.getLength();
				if (len != 12) {
					continue;
				}
				if ((reply[0]&0xff) != TreeCommand.FIND_ROOT.cmd) {
					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(hostname, port);
                int singleWidth = vps.getRfb().getSingleWidth();
                int singleHeight = vps.getRfb().getSingleHeight();
                t.setSingleSize(singleWidth, singleHeight);
                t.findRootReply(vps.getRfb().getAcceptPort());
				if(stopFlag) break;
			}
		} catch (Exception e) {
            System.out.println("tree-root-find-listener :" + e.getMessage());
		}
	}

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

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