view src/main/java/jp/ac/u_ryukyu/treevnc/BroadcastRFBListener.java @ 606:82755931810c

fix
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Wed, 19 Feb 2020 15:02:10 +0900
parents fb26a48b440d
children 42ddba3af8b2
line wrap: on
line source

package jp.ac.u_ryukyu.treevnc;

import com.glavsoft.rfb.protocol.ReceiverTask;
import com.glavsoft.transport.Reader;
import com.glavsoft.viewer.swing.ConnectionParams;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.SocketException;
import java.nio.ByteBuffer;

import static com.glavsoft.rfb.protocol.ReceiverTask.FRAMEBUFFER_UPDATE;

public class BroadcastRFBListener implements Runnable {
    public static final String Ipv4McastAddr = "224.0.0.1";
    public static final String Ipv6McastAddr = "ff02::1"; // we don't have to send IPv6, multicast on IPv4 is enough
    public static String McastAddr = Ipv4McastAddr;

	static final int BufSize = 1024*64;
	private ReceiverTask receiverTask;
	private boolean stopFlag = false;
	private TreeRFBProto rfb;
	private MulticastSocket soc;

	public BroadcastRFBListener() {
		try {
			soc = createMulticastSocket();
			System.out.println("FindRoot listening on "+ InetAddress.getByName(McastAddr));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

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

    /**
	 * Accept multicast framebufferupdate
	 *    we should accept only from acceptable server
	 *    some kind of signature
	 */
	private void rfbBroadcastLoop() {
		while (!stopFlag) {
			try {
				byte[] buf = new byte[BufSize];
				DatagramPacket recvPacket = new DatagramPacket(buf, BufSize);
				soc.receive(recvPacket);
				// String hostname = recvPacket.getAddress().getHostAddress();
				byte[] reply = recvPacket.getData();
				if (receiverTask != null) {
					if (reply[0] == FRAMEBUFFER_UPDATE) {
						receiverTask.handleMulticastFrameBufferUpdate(ByteBuffer.wrap(reply));
					}
				}
			} catch (Exception e) {
				System.out.println("broadcast-rfb-listener : " + e.getMessage());
			}
		}
	}

	/**
	 * send multicsst frame buffer update
	 *    the multicast is sent to all network interfaces supporting multicast
	 * @param buf
	 */
	public void multicastUpdateRectangle(ByteBuffer buf) {
		try {
			DatagramPacket sendPacket1 = new DatagramPacket(buf.array(), buf.limit(), InetAddress.getByName(TreeRootFinderListener.Ipv4McastAddr), ConnectionParams.DEFAULT_VNC_BROADCAST);
			soc.send(sendPacket1);
		} catch (IOException e) {
			System.out.println("cannot send UpdateRectangle.");
			e.printStackTrace();
		}
	}

    public void run() {
		rfbBroadcastLoop();
	}

    // it looks like that we never stop
	public void setStopFlag(boolean stopFlag) {
		this.stopFlag = stopFlag;
	}

	public boolean isStopFlag() {
		return stopFlag;
	}

	public MulticastSocket getSocket() {
		return soc;
	}

	public void init(TreeRFBProto rfb_, ReceiverTask receiverTask_) {
		rfb = rfb_;
		receiverTask = receiverTask_;
	}
}