changeset 3:9c99e2193277

find broadcast
author one
date Sat, 28 Jul 2012 18:15:13 +0900
parents 2a328333ba70
children 404778ac3f55
files src/wifibroadcast/WifiBroadcast.java src/wifibroadcast/WifiBroadcastTest.java src/wifibroadcast/WifiMulticast.java src/wifibroadcast/WifiMulticastChannel.java src/wifibroadcast/WifiReceiver.java
diffstat 5 files changed, 151 insertions(+), 66 deletions(-) [+]
line wrap: on
line diff
--- a/src/wifibroadcast/WifiBroadcast.java	Sat Jul 28 13:06:57 2012 +0900
+++ b/src/wifibroadcast/WifiBroadcast.java	Sat Jul 28 18:15:13 2012 +0900
@@ -1,7 +1,11 @@
 package wifibroadcast;
 
+import java.net.NetworkInterface;
 import java.io.IOException;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
 import java.net.InetSocketAddress;
+import java.net.InterfaceAddress;
 import java.net.SocketException;
 import java.net.StandardSocketOptions;
 import java.nio.ByteBuffer;
@@ -9,24 +13,40 @@
 import java.nio.channels.SelectionKey;
 import java.nio.channels.Selector;
 import java.nio.channels.spi.SelectorProvider;
+import java.util.Enumeration;
 import java.util.Iterator;
 
 public class WifiBroadcast implements WifiReceiver {
 
 	private DatagramChannel channel;
 	private Selector selector;
+	private DatagramSocket s;
 
-	public WifiBroadcast(int port) throws IOException {
+	public WifiBroadcast(int port, SocketType sender) throws IOException {
 		selector = SelectorProvider.provider().openSelector();		
 		channel = SelectorProvider.provider().openDatagramChannel();
+		s = channel.socket();
 		channel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
 		channel.configureBlocking(false);
-		try {
-			InetSocketAddress address = new InetSocketAddress("::", port);
-			channel.connect(address);
-		} catch (SocketException e) {
-			// for some bad IPv6 implementation
-			channel.connect(new InetSocketAddress(port));
+		if (sender == SocketType.Sender) {
+			s.setBroadcast(true);
+			try {
+				InetAddress address0 = getBroadcast();
+				System.out.println("Found broadcast "+address0);
+				InetSocketAddress address = new InetSocketAddress(address0, port);
+				channel.connect(address);
+			} catch (SocketException e) {
+				// for some bad IPv6 implementation
+				channel.connect(new InetSocketAddress(port));
+			}
+		} else {
+			try {
+				InetSocketAddress address = new InetSocketAddress("::", port);
+				channel.connect(address);
+			} catch (SocketException e) {
+				// for some bad IPv6 implementation
+				channel.connect(new InetSocketAddress(port));
+			}
 		}
 		channel.register(selector, SelectionKey.OP_READ);
 	}
@@ -41,11 +61,34 @@
 				testData.flip();
 				return; // one at a time
 			}
+		} else {
+			System.out.println("receiver time out");
+			testData.position(0); testData.limit(0);
 		}
 	}
+	
+	public InetAddress getBroadcast() throws SocketException {
+		Enumeration<NetworkInterface> interfaces =
+				NetworkInterface.getNetworkInterfaces();
+		while (interfaces.hasMoreElements()) {
+			NetworkInterface networkInterface = interfaces.nextElement();
+			if (networkInterface.isLoopback())
+				continue;    // Don't want to broadcast to the loopback interface
+			for (InterfaceAddress interfaceAddress :
+				networkInterface.getInterfaceAddresses()) {
+				InetAddress broadcast = interfaceAddress.getBroadcast();
+				if (broadcast == null)
+					continue;
+				// Use the address
+				return broadcast;
+			}
+		}
+		throw new SocketException();
+	}
 
 
 	public void send(ByteBuffer testData) throws IOException {
-		channel.write(testData);
+		int out = channel.write(testData);
+		System.out.println("send "+out+" bytes.");
 	}
 }
--- a/src/wifibroadcast/WifiBroadcastTest.java	Sat Jul 28 13:06:57 2012 +0900
+++ b/src/wifibroadcast/WifiBroadcastTest.java	Sat Jul 28 18:15:13 2012 +0900
@@ -3,19 +3,19 @@
 import java.io.IOException;
 import java.nio.ByteBuffer;
 
-import javax.sql.rowset.Joinable;
-
 public class WifiBroadcastTest {
-	private static int DefaultPort = 8212;
+	private static int DefaultPort = 8412;
 	private static String MCASTADDR = "224.0.0.1";
+	private static int testSize = 256;
 
 	public static void main(String args[]) {
 		int port = DefaultPort ; 
-		int count = 1024;
+		int count = 16;
 		long timeout = 1000;
 		boolean multicast = false;
 		boolean mchannel = false;
 		WifiReceiver wbr = null;
+		WifiReceiver wbs = null;
 		for(int i=0;i<args.length;i++) {
 			if (args[i].equals("-m")) multicast = true;
 			else if (args[i].equals("-channel")) mchannel = true;
@@ -25,15 +25,24 @@
 		}
 		try {
 			if (multicast) {
-				wbr = new WifiMulticast(MCASTADDR,port);
+				wbr = new WifiMulticast(MCASTADDR,port,WifiReceiver.SocketType.Receiver);
+				Thread.sleep(5000);
+				wbs = new WifiMulticast(MCASTADDR,port,WifiReceiver.SocketType.Receiver);
 			} else if (mchannel) {
-				wbr = new WifiMulticastChannel(MCASTADDR,port);
+				wbr = new WifiMulticastChannel(MCASTADDR,port,WifiReceiver.SocketType.Receiver);
+				Thread.sleep(5000);
+				wbs = new WifiMulticastChannel(MCASTADDR,port,WifiReceiver.SocketType.Sender);
 			} else {
-				wbr = new WifiBroadcast(port);
+				wbr = new WifiBroadcast(port,WifiReceiver.SocketType.Receiver);
+				Thread.sleep(5000);
+				wbs = new WifiBroadcast(port,WifiReceiver.SocketType.Sender);
 			}
 		} catch (IOException e) {
+			System.err.println("err "+e);
+		} catch (InterruptedException e) {
+			System.err.println("err "+e);
 		}
-		sender(wbr,count);
+		sender(wbs,count);
 		receiver(wbr,count, timeout);
 	}
 
@@ -48,16 +57,20 @@
 
 	public static void sender(final WifiReceiver wbs, final int count) {
 		Runnable sender = new Runnable() {
+
 			@Override
 			public void run() {
-				ByteBuffer testData = getTestData(4096);
+				ByteBuffer testData = getTestData(testSize);
+				int i = 0;
 				try {
-					for(int i = 0; i<count;i++) {
+					Thread.sleep(1000);
+					for(i = 0; i<count;i++) {
 						testData.putInt(0, i);
 						wbs.send(testData);
 						testData.flip();
 					}
-				} catch (IOException e) {
+				} catch (Exception e) {
+					System.err.println("sender error at "+i+" "+e);
 				}
 		}
 		};
@@ -87,20 +100,24 @@
 			@Override
 			public void run() {
 				ByteBuffer testData = ByteBuffer.allocate(4096);
-				int num = 0, bad = 0;
+				int bad = 0, good = 0;
 				try {
 					for(int i = 0; running &&  i<count;i++) {
 						testData.clear();
 						wbr.recieve(testData,timeout);
 						if (!testData.hasRemaining()) continue;
+						System.out.println("receive "+testData.remaining()+" bytes.");
 						int seq = testData.getInt();
 						if (seq!=i) {
 							bad++; i = seq;
+						} else {
+							good++;
 						}
 					}
-				} catch (IOException e) {
+				} catch (Exception e) {
+					System.err.println("receiver error "+e);
 				}
-				System.out.println("get "+num+" packets, "+bad+" losts.");
+				System.out.println("get "+good+" packets, "+bad+" losts.");
 		}
 		};
 		Thread r = new Thread(receiver); r.start();
--- a/src/wifibroadcast/WifiMulticast.java	Sat Jul 28 13:06:57 2012 +0900
+++ b/src/wifibroadcast/WifiMulticast.java	Sat Jul 28 18:15:13 2012 +0900
@@ -2,41 +2,45 @@
 
 import java.io.IOException;
 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;
 
-	import java.net.DatagramPacket;
-	import java.net.InetAddress;
+import java.net.DatagramPacket;
+import java.net.InetAddress;
 import java.net.MulticastSocket;
 
-	public class WifiMulticast implements WifiReceiver {
-		private MulticastSocket soc;
-		private InetAddress mAddr;
-		private int port;
-		
-		public WifiMulticast(String mCASTADDR, int port) throws IOException {
-			this.port = port;
-			try {
-				mAddr = InetAddress.getByName(mCASTADDR);
-				soc = new MulticastSocket(port);
-				soc.joinGroup(mAddr);
-			} catch (IOException e) {
-				e.printStackTrace();
-			}
+public class WifiMulticast implements WifiReceiver {
+	private MulticastSocket soc;
+	private InetAddress mAddr;
+	private int port;
+
+	public WifiMulticast(String mCASTADDR, int port, SocketType sender) throws IOException {
+		this.port = port;
+		try {
+			mAddr = InetAddress.getByName(mCASTADDR);
+			soc = new MulticastSocket(port);
+			soc.joinGroup(mAddr);
+		} catch (IOException e) {
+			e.printStackTrace();
 		}
-
-		@Override
-		public void recieve(ByteBuffer testData, long timeout) throws IOException {
-			DatagramPacket packet = new DatagramPacket(testData.array(),testData.capacity());
-			soc.receive(packet);
-			testData.limit(packet.getLength());
-			testData.position(0);
-		}
-
-		@Override
-		public void send(ByteBuffer testData) throws IOException {
-			DatagramPacket sendPacket = new DatagramPacket(testData.array(), testData.limit(),mAddr, port);
-			soc.send(sendPacket);		
-		}
-
 	}
 
+	@Override
+	public void recieve(ByteBuffer testData, long timeout) throws IOException {
+		DatagramPacket packet = new DatagramPacket(testData.array(),testData.capacity());
+		soc.receive(packet);
+		testData.limit(packet.getLength());
+		testData.position(0);
+	}
+
+	@Override
+	public void send(ByteBuffer testData) throws IOException {
+		DatagramPacket sendPacket = new DatagramPacket(testData.array(), testData.limit(),mAddr, port);
+		soc.send(sendPacket);		
+		testData.position(testData.limit());
+	}
+
+}
+
--- a/src/wifibroadcast/WifiMulticastChannel.java	Sat Jul 28 13:06:57 2012 +0900
+++ b/src/wifibroadcast/WifiMulticastChannel.java	Sat Jul 28 18:15:13 2012 +0900
@@ -9,31 +9,50 @@
 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 {
 	private InetAddress mAddr;
 	private DatagramChannel dc;
 	private SocketAddress sAddr;
-	
-	public WifiMulticastChannel(String mCASTADDR, int port) throws IOException {
-	     // join multicast group on this interface, and also use this
-	     // interface for outgoing multicast datagrams
-     	  NetworkInterface ni = NetworkInterface.getByName("en1");
+	private Selector selector;
+
+	public WifiMulticastChannel(String mCASTADDR, int port, 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("en1");
+		if (ni==null) {
+			System.err.println("Can't open network interface "+"en1");
+			throw new IOException();
+		}
 
-	     dc = DatagramChannel.open(StandardProtocolFamily.INET)
-	         .setOption(StandardSocketOptions.SO_REUSEADDR, true)
-	         .bind(sAddr = new InetSocketAddress(port))
-	         .setOption(StandardSocketOptions.IP_MULTICAST_IF, ni);
+		if (!ni.supportsMulticast()) {
+			System.err.println("Network interface does not support multicast"+"en1");
+			throw new IOException();
+		}
 
-	     mAddr = InetAddress.getByName(mCASTADDR);
+		dc = DatagramChannel.open(StandardProtocolFamily.INET)
+				.setOption(StandardSocketOptions.SO_REUSEADDR, true)
+				.bind(sAddr = new InetSocketAddress(port))
+				.setOption(StandardSocketOptions.IP_MULTICAST_IF, ni);
+
+		mAddr = InetAddress.getByName(mCASTADDR);
 
 		dc.join(mAddr, ni);
-	 
+		dc.configureBlocking(false);
+		dc.register(selector, SelectionKey.OP_READ);
 	}
 
 	@Override
 	public void recieve(ByteBuffer testData, long timeout) throws IOException {
-		dc.receive(testData);
+		if (selector.select(timeout)>0) {
+			dc.receive(testData);
+		} else {
+			testData.limit(0); testData.position(0);
+		}
 	}
 
 	@Override
--- a/src/wifibroadcast/WifiReceiver.java	Sat Jul 28 13:06:57 2012 +0900
+++ b/src/wifibroadcast/WifiReceiver.java	Sat Jul 28 18:15:13 2012 +0900
@@ -5,6 +5,8 @@
 
 public interface WifiReceiver {
 
+	public enum SocketType {Sender , Receiver } ;
+	
 	void recieve(ByteBuffer testData, long timeout) throws IOException;
 
 	void send(ByteBuffer testData) throws IOException;