view src/main/jp/ac/uryukyu/ie/kono/wifibroadcast/WifiMulticastChannel.java @ 26:42ecbd9364fa

gradle
author oshiroo
date Wed, 28 Nov 2018 17:34:23 +0900
parents src/wifibroadcast/WifiMulticastChannel.java@48d458bb921a
children
line wrap: on
line source

package wifibroadcast;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.SocketAddress;
import java.net.StandardProtocolFamily;
import java.net.StandardSocketOptions;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.spi.SelectorProvider;

public class WifiMulticastChannel implements WifiReceiver {
	protected InetAddress mAddr;
	protected DatagramChannel dc;
	protected SocketAddress sAddr;
	// select on DatagramChannel does not work now
	protected Selector selector;
	protected boolean selectMode = false; 
	
	public WifiMulticastChannel() {}

	public WifiMulticastChannel(int id, String mCASTADDR, int port,String nis,  SocketType sender) throws IOException {
		// join multicast group on this interface, and also use this
		// interface for outgoing multicast datagrams
		selector = SelectorProvider.provider().openSelector();    
		NetworkInterface ni = NetworkInterface.getByName(nis);
		if (ni==null) {
			System.err.println("Can't open network interface "+nis);
			throw new IOException();
		}

		if (!ni.supportsMulticast()) {
			System.err.println("Network interface does not support multicast"+nis);
			throw new IOException();
		}

		// dc = SelectorProvider.provider().openDatagramChannel(StandardProtocolFamily.INET);
		dc = DatagramChannel.open(StandardProtocolFamily.INET);
		dc.setOption(StandardSocketOptions.SO_REUSEADDR, true);
		dc.setOption(StandardSocketOptions.IP_MULTICAST_IF, ni);
		mAddr = InetAddress.getByName(mCASTADDR);
		sAddr = new InetSocketAddress(mAddr,port);
		dc.join(mAddr, ni);
		
		if (sender == SocketType.Receiver) {
			dc.bind(new InetSocketAddress(port));
			if (selectMode) {
				dc.configureBlocking(false);
				dc.register(selector, SelectionKey.OP_READ);
			}
		}
	}

	@Override
	public void recieve(ByteBuffer testData, long timeout) throws IOException {
		if (selectMode && selector.select(timeout)==0) {
			System.out.println("bad select "+timeout);
			testData.limit(0); testData.position(0);
			return;
		}
		SocketAddress s = dc.receive(testData);
		testData.flip();
		System.out.println("From "+s+" "+testData.remaining()+" bytes.");
	}

	@Override
	public void send(ByteBuffer testData) throws IOException {
		while(testData.hasRemaining()) {
			dc.send(testData, sAddr);
		}
//		try {
//			Thread.sleep(100);
//		} catch (InterruptedException e) {
//		}
	}

    @Override
    public void selectMode(boolean mode) {
        selectMode = mode;
    }

}