| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.harmony.tests.java.net; |
| |
| import java.io.IOException; |
| import java.net.BindException; |
| import java.net.DatagramPacket; |
| import java.net.Inet4Address; |
| import java.net.Inet6Address; |
| import java.net.InetAddress; |
| import java.net.InetSocketAddress; |
| import java.net.MulticastSocket; |
| import java.net.NetworkInterface; |
| import java.net.SocketAddress; |
| import java.net.SocketException; |
| import java.net.SocketTimeoutException; |
| import java.util.ArrayList; |
| import java.util.Enumeration; |
| import java.util.List; |
| import libcore.junit.junit3.TestCaseWithRules; |
| import libcore.junit.util.ResourceLeakageDetector; |
| import org.junit.Rule; |
| import org.junit.rules.TestRule; |
| |
| public class MulticastSocketTest extends TestCaseWithRules { |
| @Rule |
| public TestRule guardRule = ResourceLeakageDetector.getRule(); |
| |
| private static InetAddress lookup(String s) { |
| try { |
| return InetAddress.getByName(s); |
| } catch (IOException ex) { |
| throw new RuntimeException(ex); |
| } |
| } |
| |
| // These IP addresses aren't inherently "good" or "bad"; they're just used like that. |
| // We use the "good" addresses for our actual group, and the "bad" addresses are for |
| // a group that we won't actually set up. |
| |
| private static InetAddress GOOD_IPv4 = lookup("224.0.0.3"); |
| private static InetAddress BAD_IPv4 = lookup("224.0.0.4"); |
| private static InetAddress GOOD_IPv6 = lookup("ff05::7:7"); |
| private static InetAddress BAD_IPv6 = lookup("ff05::7:8"); |
| |
| private NetworkInterface loopbackInterface; |
| private NetworkInterface ipv4NetworkInterface; |
| private NetworkInterface ipv6NetworkInterface; |
| private boolean supportsMulticast; |
| |
| @Override |
| protected void setUp() throws Exception { |
| // The loopback interface isn't actually useful for sending/receiving multicast messages |
| // but it can be used as a dummy for tests where that does not matter. |
| loopbackInterface = NetworkInterface.getByInetAddress(InetAddress.getLoopbackAddress()); |
| assertNotNull(loopbackInterface); |
| assertTrue(loopbackInterface.isLoopback()); |
| assertFalse(loopbackInterface.supportsMulticast()); |
| |
| Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); |
| assertNotNull(interfaces); |
| |
| // Determine if the device is marked to support multicast or not. If this propery is not |
| // set we assume the device has an interface capable of supporting multicast. |
| supportsMulticast = Boolean.parseBoolean( |
| System.getProperty("android.cts.device.multicast", "true")); |
| if (!supportsMulticast) { |
| return; |
| } |
| |
| while (interfaces.hasMoreElements() |
| && (ipv4NetworkInterface == null || ipv6NetworkInterface == null)) { |
| NetworkInterface nextInterface = interfaces.nextElement(); |
| if (willWorkForMulticast(nextInterface)) { |
| Enumeration<InetAddress> addresses = nextInterface.getInetAddresses(); |
| while (addresses.hasMoreElements()) { |
| final InetAddress nextAddress = addresses.nextElement(); |
| if (nextAddress instanceof Inet6Address && ipv6NetworkInterface == null) { |
| ipv6NetworkInterface = nextInterface; |
| } else if (nextAddress instanceof Inet4Address |
| && ipv4NetworkInterface == null) { |
| ipv4NetworkInterface = nextInterface; |
| } |
| } |
| } |
| } |
| assertTrue("Test environment must have at least one interface capable of multicast for IPv4" |
| + " and IPv6", |
| ipv4NetworkInterface != null && ipv6NetworkInterface != null); |
| } |
| |
| public void test_Constructor() throws IOException { |
| if (!supportsMulticast) { |
| return; |
| } |
| // Regression test for 497. |
| MulticastSocket s = new MulticastSocket(); |
| // Regression test for Harmony-1162. |
| assertTrue(s.getReuseAddress()); |
| |
| s.close(); |
| } |
| |
| public void test_ConstructorI() throws IOException { |
| if (!supportsMulticast) { |
| return; |
| } |
| MulticastSocket orig = new MulticastSocket(); |
| int port = orig.getLocalPort(); |
| orig.close(); |
| |
| MulticastSocket dup = new MulticastSocket(port); |
| // Regression test for Harmony-1162. |
| assertTrue(dup.getReuseAddress()); |
| dup.close(); |
| } |
| |
| public void test_getInterface() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| // Validate that we get the expected response when one was not set. |
| MulticastSocket mss = new MulticastSocket(0); |
| // We expect an ANY address in this case. |
| assertTrue(mss.getInterface().isAnyLocalAddress()); |
| |
| // Validate that we get the expected response when we set via setInterface. |
| Enumeration addresses = ipv4NetworkInterface.getInetAddresses(); |
| if (addresses.hasMoreElements()) { |
| InetAddress firstAddress = (InetAddress) addresses.nextElement(); |
| mss.setInterface(firstAddress); |
| assertEquals("getNetworkInterface did not return interface set by setInterface", |
| firstAddress, mss.getInterface()); |
| |
| mss.close(); |
| mss = new MulticastSocket(0); |
| mss.setNetworkInterface(ipv4NetworkInterface); |
| assertEquals("getInterface did not return interface set by setNetworkInterface", |
| ipv4NetworkInterface, NetworkInterface.getByInetAddress(mss.getInterface())); |
| } |
| |
| mss.close(); |
| } |
| |
| public void test_getNetworkInterface() throws IOException { |
| if (!supportsMulticast) { |
| return; |
| } |
| // Validate that we get the expected response when one was not set. |
| MulticastSocket mss = new MulticastSocket(0); |
| NetworkInterface theInterface = mss.getNetworkInterface(); |
| assertTrue( |
| "network interface returned wrong network interface when not set:" + theInterface, |
| theInterface.getInetAddresses().hasMoreElements()); |
| InetAddress firstAddress = theInterface.getInetAddresses().nextElement(); |
| // Validate we the first address in the network interface is the ANY address. |
| assertTrue(firstAddress.isAnyLocalAddress()); |
| |
| mss.setNetworkInterface(ipv4NetworkInterface); |
| assertEquals("getNetworkInterface did not return interface set by setNeworkInterface", |
| ipv4NetworkInterface, mss.getNetworkInterface()); |
| |
| mss.setNetworkInterface(loopbackInterface); |
| assertEquals( |
| "getNetworkInterface did not return network interface set by second" |
| + " setNetworkInterface call", |
| loopbackInterface, mss.getNetworkInterface()); |
| mss.close(); |
| |
| if (ipv6NetworkInterface != null) { |
| mss = new MulticastSocket(0); |
| mss.setNetworkInterface(ipv6NetworkInterface); |
| assertEquals("getNetworkInterface did not return interface set by setNeworkInterface", |
| ipv6NetworkInterface, mss.getNetworkInterface()); |
| mss.close(); |
| } |
| |
| // Validate that we get the expected response when we set via setInterface. |
| mss = new MulticastSocket(0); |
| Enumeration addresses = ipv4NetworkInterface.getInetAddresses(); |
| if (addresses.hasMoreElements()) { |
| firstAddress = (InetAddress) addresses.nextElement(); |
| mss.setInterface(firstAddress); |
| assertEquals("getNetworkInterface did not return interface set by setInterface", |
| ipv4NetworkInterface, mss.getNetworkInterface()); |
| } |
| mss.close(); |
| } |
| |
| public void test_getTimeToLive() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| MulticastSocket mss = new MulticastSocket(); |
| mss.setTimeToLive(120); |
| assertEquals("Returned incorrect 1st TTL", 120, mss.getTimeToLive()); |
| mss.setTimeToLive(220); |
| assertEquals("Returned incorrect 2nd TTL", 220, mss.getTimeToLive()); |
| mss.close(); |
| } |
| |
| public void test_getTTL() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| MulticastSocket mss = new MulticastSocket(); |
| mss.setTTL((byte) 120); |
| assertEquals("Returned incorrect TTL", 120, mss.getTTL()); |
| mss.close(); |
| } |
| |
| public void test_joinGroupLjava_net_InetAddress_IPv4() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| test_joinGroupLjava_net_InetAddress(GOOD_IPv4); |
| } |
| |
| public void test_joinGroupLjava_net_InetAddress_IPv6() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| test_joinGroupLjava_net_InetAddress(GOOD_IPv6); |
| } |
| |
| private void test_joinGroupLjava_net_InetAddress(InetAddress group) throws Exception { |
| MulticastSocket receivingSocket = createReceivingSocket(0); |
| receivingSocket.joinGroup(group); |
| |
| String msg = "Hello World"; |
| MulticastSocket sendingSocket = new MulticastSocket(receivingSocket.getLocalPort()); |
| InetSocketAddress groupAddress = |
| new InetSocketAddress(group, receivingSocket.getLocalPort()); |
| DatagramPacket sdp = createSendDatagramPacket(groupAddress, msg); |
| sendingSocket.send(sdp, (byte) 10 /* ttl */); |
| |
| DatagramPacket rdp = createReceiveDatagramPacket(); |
| receivingSocket.receive(rdp); |
| String receivedMessage = extractMessage(rdp); |
| assertEquals("Group member did not recv data", msg, receivedMessage); |
| |
| sendingSocket.close(); |
| receivingSocket.close(); |
| } |
| |
| public void test_joinGroup_null_null() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| MulticastSocket mss = new MulticastSocket(0); |
| try { |
| mss.joinGroup(null, null); |
| fail(); |
| } catch (IllegalArgumentException expected) { |
| } |
| mss.close(); |
| } |
| |
| public void test_joinGroup_non_multicast_address_IPv4() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| MulticastSocket mss = new MulticastSocket(0); |
| try { |
| mss.joinGroup(new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 0), null); |
| fail(); |
| } catch (IOException expected) { |
| } |
| mss.close(); |
| } |
| |
| public void test_joinGroup_non_multicast_address_IPv6() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| MulticastSocket mss = new MulticastSocket(0); |
| try { |
| mss.joinGroup(new InetSocketAddress(InetAddress.getByName("::1"), 0), null); |
| fail(); |
| } catch (IOException expected) { |
| } |
| mss.close(); |
| } |
| |
| public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv4() |
| throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface( |
| ipv4NetworkInterface, GOOD_IPv4, BAD_IPv4); |
| } |
| |
| public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv6() |
| throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface( |
| ipv6NetworkInterface, GOOD_IPv6, BAD_IPv6); |
| } |
| |
| public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv4_nullInterface() |
| throws Exception { |
| test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface(null, GOOD_IPv4, BAD_IPv4); |
| } |
| |
| public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv6_nullInterface() |
| throws Exception { |
| test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface(null, GOOD_IPv6, BAD_IPv6); |
| } |
| |
| private void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface( |
| NetworkInterface networkInterface, InetAddress group, InetAddress group2) |
| throws Exception { |
| // Create the sending socket and specify the interface to use as needed (otherwise use the |
| // default). |
| MulticastSocket sendingSocket = new MulticastSocket(0); |
| if (networkInterface != null) { |
| sendingSocket.setNetworkInterface(networkInterface); |
| } |
| sendingSocket.setTimeToLive(2); |
| |
| MulticastSocket receivingSocket = createReceivingSocket(0); |
| InetSocketAddress groupAddress = |
| new InetSocketAddress(group, receivingSocket.getLocalPort()); |
| // Join the group. A null network interface is valid and means "use default". |
| receivingSocket.joinGroup(groupAddress, networkInterface); |
| |
| String msg = "Hello World"; |
| DatagramPacket sdp = createSendDatagramPacket(groupAddress, msg); |
| sendingSocket.send(sdp); |
| |
| DatagramPacket rdp = createReceiveDatagramPacket(); |
| receivingSocket.receive(rdp); |
| // Now validate that we received the data as expected. |
| assertEquals("Group member did not recv data", msg, extractMessage(rdp)); |
| receivingSocket.close(); |
| sendingSocket.close(); |
| |
| // Create the sending socket and specify the interface to use as needed (otherwise use the |
| // default). |
| sendingSocket = new MulticastSocket(0); |
| if (networkInterface != null) { |
| sendingSocket.setNetworkInterface(networkInterface); |
| } |
| sendingSocket.setTimeToLive(10); |
| |
| receivingSocket = createReceivingSocket(0); |
| groupAddress = new InetSocketAddress(group, receivingSocket.getLocalPort()); |
| // Join the group. A null network interface is valid and means "use default". |
| receivingSocket.joinGroup(groupAddress, networkInterface); |
| |
| msg = "Hello World - Different Group"; |
| InetSocketAddress group2Address = |
| new InetSocketAddress(group2, receivingSocket.getLocalPort()); |
| sdp = createSendDatagramPacket(group2Address, msg); |
| sendingSocket.send(sdp); |
| |
| rdp = createReceiveDatagramPacket(); |
| try { |
| receivingSocket.receive(rdp); |
| fail("Expected timeout"); |
| } catch (SocketTimeoutException expected) { |
| } |
| |
| receivingSocket.close(); |
| sendingSocket.close(); |
| } |
| |
| public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| // Check that we can join on specific interfaces and that we only receive if data is |
| // received on that interface. This test is only really useful on devices with multiple |
| // non-loopback interfaces. |
| |
| List<NetworkInterface> realInterfaces = new ArrayList<NetworkInterface>(); |
| Enumeration<NetworkInterface> theInterfaces = NetworkInterface.getNetworkInterfaces(); |
| while (theInterfaces.hasMoreElements()) { |
| NetworkInterface thisInterface = theInterfaces.nextElement(); |
| // Skip interfaces that do not support multicast - there's no point in proving |
| // they cannot send / receive multicast messages. |
| if (willWorkForMulticast(thisInterface)) { |
| realInterfaces.add(thisInterface); |
| } |
| } |
| |
| for (NetworkInterface thisInterface : realInterfaces) { |
| // Find a suitable group IP and interface to use to sent packets to thisInterface. |
| Enumeration<InetAddress> addresses = thisInterface.getInetAddresses(); |
| |
| NetworkInterface sendingInterface = null; |
| InetAddress group = null; |
| if (addresses.hasMoreElements()) { |
| InetAddress firstAddress = addresses.nextElement(); |
| if (firstAddress instanceof Inet4Address) { |
| group = GOOD_IPv4; |
| sendingInterface = ipv4NetworkInterface; |
| } else { |
| // if this interface only seems to support IPV6 addresses |
| group = GOOD_IPv6; |
| sendingInterface = ipv6NetworkInterface; |
| } |
| } |
| |
| // Create a receivingSocket which is joined to the group and has only asked for packets |
| // on thisInterface. |
| MulticastSocket receivingSocket = createReceivingSocket(0); |
| InetSocketAddress groupAddress = |
| new InetSocketAddress(group, receivingSocket.getLocalPort()); |
| receivingSocket.joinGroup(groupAddress, thisInterface); |
| |
| // Now send out a packet on sendingInterface. We should only see the packet if we send |
| // it on thisInterface. |
| MulticastSocket sendingSocket = new MulticastSocket(0); |
| sendingSocket.setNetworkInterface(sendingInterface); |
| String msg = "Hello World - Again " + thisInterface.getName(); |
| DatagramPacket sdp = createSendDatagramPacket(groupAddress, msg); |
| sendingSocket.send(sdp); |
| |
| DatagramPacket rdp = createReceiveDatagramPacket(); |
| try { |
| receivingSocket.receive(rdp); |
| |
| // If the packet is received.... |
| assertEquals(thisInterface, sendingInterface); |
| assertEquals("Group member did not recv data when bound on specific interface", |
| msg, extractMessage(rdp)); |
| } catch (SocketTimeoutException e) { |
| // If the packet was not received... |
| assertTrue(!thisInterface.equals(sendingInterface)); |
| } |
| |
| receivingSocket.close(); |
| sendingSocket.close(); |
| } |
| } |
| |
| public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins_IPv4() |
| throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins( |
| ipv4NetworkInterface, GOOD_IPv4); |
| } |
| |
| public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins_IPv6() |
| throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins( |
| ipv6NetworkInterface, GOOD_IPv6); |
| } |
| |
| private void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins( |
| NetworkInterface networkInterface, InetAddress group) throws Exception { |
| // Validate that we can join the same address on two different interfaces but not on the |
| // same interface. |
| MulticastSocket mss = new MulticastSocket(0); |
| SocketAddress groupSockAddr = new InetSocketAddress(group, mss.getLocalPort()); |
| mss.joinGroup(groupSockAddr, networkInterface); |
| mss.joinGroup(groupSockAddr, loopbackInterface); |
| try { |
| mss.joinGroup(groupSockAddr, networkInterface); |
| fail("Did not get expected exception when joining for second time on same interface"); |
| } catch (IOException e) { |
| } |
| mss.close(); |
| } |
| |
| public void test_leaveGroupLjava_net_InetAddress_IPv4() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| test_leaveGroupLjava_net_InetAddress(GOOD_IPv4); |
| } |
| |
| public void test_leaveGroupLjava_net_InetAddress_IPv6() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| test_leaveGroupLjava_net_InetAddress(GOOD_IPv6); |
| } |
| |
| private void test_leaveGroupLjava_net_InetAddress(InetAddress group) throws Exception { |
| String msg = "Hello World"; |
| MulticastSocket mss = new MulticastSocket(0); |
| InetSocketAddress groupAddress = new InetSocketAddress(group, mss.getLocalPort()); |
| DatagramPacket sdp = createSendDatagramPacket(groupAddress, msg); |
| mss.send(sdp, (byte) 10 /* ttl */); |
| try { |
| // Try to leave a group we didn't join. |
| mss.leaveGroup(group); |
| fail(); |
| } catch (IOException expected) { |
| } |
| mss.close(); |
| } |
| |
| public void test_leaveGroup_null_null() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| MulticastSocket mss = new MulticastSocket(0); |
| try { |
| mss.leaveGroup(null, null); |
| fail(); |
| } catch (IllegalArgumentException expected) { |
| } |
| mss.close(); |
| } |
| |
| public void test_leaveGroup_non_multicast_address_IPv4() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| MulticastSocket mss = new MulticastSocket(0); |
| try { |
| mss.leaveGroup(new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 0), null); |
| fail(); |
| } catch (IOException expected) { |
| } |
| mss.close(); |
| } |
| |
| public void test_leaveGroup_non_multicast_address_IPv6() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| MulticastSocket mss = new MulticastSocket(0); |
| try { |
| mss.leaveGroup(new InetSocketAddress(InetAddress.getByName("::1"), 0), null); |
| fail(); |
| } catch (IOException expected) { |
| } |
| mss.close(); |
| } |
| |
| public void test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv4() |
| throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface( |
| ipv4NetworkInterface, GOOD_IPv4, BAD_IPv4); |
| } |
| |
| public void test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv6() |
| throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface( |
| ipv6NetworkInterface, GOOD_IPv6, BAD_IPv6); |
| } |
| |
| private void test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface( |
| NetworkInterface networkInterface, InetAddress group, InetAddress group2) |
| throws Exception { |
| SocketAddress groupSockAddr = null; |
| SocketAddress groupSockAddr2 = null; |
| |
| try (MulticastSocket mss = new MulticastSocket(0)) { |
| groupSockAddr = new InetSocketAddress(group, mss.getLocalPort()); |
| mss.joinGroup(groupSockAddr, null); |
| mss.leaveGroup(groupSockAddr, null); |
| try { |
| mss.leaveGroup(groupSockAddr, null); |
| fail("Did not get exception when trying to leave group that was already left"); |
| } catch (IOException expected) { |
| } |
| |
| groupSockAddr2 = new InetSocketAddress(group2, mss.getLocalPort()); |
| mss.joinGroup(groupSockAddr, networkInterface); |
| try { |
| mss.leaveGroup(groupSockAddr2, networkInterface); |
| fail("Did not get exception when trying to leave group that was never joined"); |
| } catch (IOException expected) { |
| } |
| |
| mss.leaveGroup(groupSockAddr, networkInterface); |
| |
| mss.joinGroup(groupSockAddr, networkInterface); |
| try { |
| mss.leaveGroup(groupSockAddr, loopbackInterface); |
| fail("Did not get exception when trying to leave group on wrong interface " + |
| "joined on [" + networkInterface + "] left on [" + loopbackInterface + "]"); |
| } catch (IOException expected) { |
| } |
| } |
| } |
| |
| public void test_sendLjava_net_DatagramPacketB_IPv4() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| test_sendLjava_net_DatagramPacketB(GOOD_IPv4); |
| } |
| |
| public void test_sendLjava_net_DatagramPacketB_IPv6() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| test_sendLjava_net_DatagramPacketB(GOOD_IPv6); |
| } |
| |
| private void test_sendLjava_net_DatagramPacketB(InetAddress group) throws Exception { |
| String msg = "Hello World"; |
| MulticastSocket sendingSocket = new MulticastSocket(0); |
| MulticastSocket receivingSocket = createReceivingSocket(sendingSocket.getLocalPort()); |
| receivingSocket.joinGroup(group); |
| |
| InetSocketAddress groupAddress = new InetSocketAddress(group, sendingSocket.getLocalPort()); |
| DatagramPacket sdp = createSendDatagramPacket(groupAddress, msg); |
| sendingSocket.send(sdp, (byte) 10 /* ttl */); |
| sendingSocket.close(); |
| |
| DatagramPacket rdp = createReceiveDatagramPacket(); |
| receivingSocket.receive(rdp); |
| String receivedMessage = extractMessage(rdp); |
| assertEquals("Failed to send data. Received " + rdp.getLength(), msg, receivedMessage); |
| receivingSocket.close(); |
| } |
| |
| public void test_setInterfaceLjava_net_InetAddress() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| MulticastSocket mss = new MulticastSocket(); |
| mss.setInterface(InetAddress.getLocalHost()); |
| InetAddress theInterface = mss.getInterface(); |
| // Under IPV6 we are not guaranteed to get the same address back as the address that was |
| // set, all we should be guaranteed is that we get an address on the same interface. |
| if (theInterface instanceof Inet6Address) { |
| assertEquals("Failed to return correct interface IPV6", |
| NetworkInterface.getByInetAddress(mss.getInterface()), |
| NetworkInterface.getByInetAddress(theInterface)); |
| } else { |
| assertTrue("Failed to return correct interface IPV4 got:" + mss.getInterface() + |
| " expected: " + InetAddress.getLocalHost(), |
| mss.getInterface().equals(InetAddress.getLocalHost())); |
| } |
| mss.close(); |
| } |
| |
| public void test_setInterface_unbound_address_IPv4() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| test_setInterface_unbound_address(GOOD_IPv4); |
| } |
| |
| public void test_setInterface_unbound_address_IPv6() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| test_setInterface_unbound_address(GOOD_IPv6); |
| } |
| |
| // Regression test for Harmony-2410. |
| private void test_setInterface_unbound_address(InetAddress address) throws Exception { |
| MulticastSocket mss = new MulticastSocket(); |
| try { |
| mss.setInterface(address); |
| fail(); |
| } catch (SocketException expected) { |
| } |
| mss.close(); |
| } |
| |
| public void test_setNetworkInterfaceLjava_net_NetworkInterface_null() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| // Validate that null interface is handled ok. |
| MulticastSocket mss = new MulticastSocket(); |
| try { |
| mss.setNetworkInterface(null); |
| fail("No socket exception when we set then network interface with NULL"); |
| } catch (SocketException ex) { |
| } |
| mss.close(); |
| } |
| |
| public void test_setNetworkInterfaceLjava_net_NetworkInterface_round_trip() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| // Validate that we can get and set the interface. |
| MulticastSocket mss = new MulticastSocket(); |
| mss.setNetworkInterface(ipv4NetworkInterface); |
| assertEquals("Interface did not seem to be set by setNeworkInterface", |
| ipv4NetworkInterface, mss.getNetworkInterface()); |
| mss.close(); |
| } |
| |
| public void test_setNetworkInterfaceLjava_net_NetworkInterface_IPv4() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| test_setNetworkInterfaceLjava_net_NetworkInterface(GOOD_IPv4); |
| } |
| |
| public void test_setNetworkInterfaceLjava_net_NetworkInterface_IPv6() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| test_setNetworkInterfaceLjava_net_NetworkInterface(GOOD_IPv6); |
| } |
| |
| private void test_setNetworkInterfaceLjava_net_NetworkInterface(InetAddress group) |
| throws IOException, InterruptedException { |
| // Set up the receiving socket and join the group. |
| Enumeration theInterfaces = NetworkInterface.getNetworkInterfaces(); |
| while (theInterfaces.hasMoreElements()) { |
| NetworkInterface thisInterface = (NetworkInterface) theInterfaces.nextElement(); |
| if (willWorkForMulticast(thisInterface)) { |
| if ((!(thisInterface.getInetAddresses().nextElement()).isLoopbackAddress())) { |
| MulticastSocket receivingSocket = createReceivingSocket(0); |
| InetSocketAddress groupAddress = |
| new InetSocketAddress(group, receivingSocket.getLocalPort()); |
| receivingSocket.joinGroup(groupAddress, thisInterface); |
| |
| // Send the packets on a particular interface. The source address in the |
| // received packet should be one of the addresses for the interface set. |
| MulticastSocket sendingSocket = new MulticastSocket(0); |
| sendingSocket.setNetworkInterface(thisInterface); |
| String msg = thisInterface.getName(); |
| DatagramPacket sdp = createSendDatagramPacket(groupAddress, msg); |
| sendingSocket.send(sdp); |
| |
| DatagramPacket rdp = createReceiveDatagramPacket(); |
| receivingSocket.receive(rdp); |
| String receivedMessage = extractMessage(rdp); |
| assertEquals("Group member did not recv data sent on a specific interface", |
| msg, receivedMessage); |
| // Stop the server. |
| receivingSocket.close(); |
| sendingSocket.close(); |
| } |
| } |
| } |
| } |
| |
| public void test_setTimeToLiveI() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| MulticastSocket mss = new MulticastSocket(); |
| mss.setTimeToLive(120); |
| assertEquals("Returned incorrect 1st TTL", 120, mss.getTimeToLive()); |
| mss.setTimeToLive(220); |
| assertEquals("Returned incorrect 2nd TTL", 220, mss.getTimeToLive()); |
| mss.close(); |
| } |
| |
| public void test_setTTLB() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| MulticastSocket mss = new MulticastSocket(); |
| mss.setTTL((byte) 120); |
| assertEquals("Failed to set TTL", 120, mss.getTTL()); |
| mss.close(); |
| } |
| |
| public void test_ConstructorLjava_net_SocketAddress() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| MulticastSocket ms = new MulticastSocket((SocketAddress) null); |
| assertTrue("should not be bound", !ms.isBound() && !ms.isClosed() && !ms.isConnected()); |
| ms.bind(null); |
| assertTrue("should be bound", ms.isBound() && !ms.isClosed() && !ms.isConnected()); |
| ms.close(); |
| assertTrue("should be closed", ms.isClosed()); |
| |
| ms = new MulticastSocket(0); |
| assertTrue("should be bound", ms.isBound() && !ms.isClosed() && !ms.isConnected()); |
| ms.close(); |
| assertTrue("should be closed", ms.isClosed()); |
| |
| ms = new MulticastSocket(0); |
| assertTrue("should be bound", ms.isBound() && !ms.isClosed() && !ms.isConnected()); |
| ms.close(); |
| assertTrue("should be closed", ms.isClosed()); |
| |
| try { |
| new MulticastSocket(new InetSocketAddress("unresolvedname", 31415)); |
| fail(); |
| } catch (IOException expected) { |
| } |
| |
| // Regression test for Harmony-1162. |
| InetSocketAddress addr = new InetSocketAddress("0.0.0.0", 0); |
| MulticastSocket s = new MulticastSocket(addr); |
| assertTrue(s.getReuseAddress()); |
| s.close(); |
| } |
| |
| public void test_getLoopbackMode() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| MulticastSocket ms = new MulticastSocket(null); |
| assertTrue("should not be bound", !ms.isBound() && !ms.isClosed() && !ms.isConnected()); |
| ms.getLoopbackMode(); |
| assertTrue("should not be bound", !ms.isBound() && !ms.isClosed() && !ms.isConnected()); |
| ms.close(); |
| assertTrue("should be closed", ms.isClosed()); |
| } |
| |
| public void test_setLoopbackModeZ() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| MulticastSocket ms = new MulticastSocket(); |
| ms.setLoopbackMode(true); |
| assertTrue("loopback should be true", ms.getLoopbackMode()); |
| ms.setLoopbackMode(false); |
| assertTrue("loopback should be false", !ms.getLoopbackMode()); |
| ms.close(); |
| assertTrue("should be closed", ms.isClosed()); |
| } |
| |
| public void test_setLoopbackModeSendReceive_IPv4() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| test_setLoopbackModeSendReceive(GOOD_IPv4); |
| } |
| |
| public void test_setLoopbackModeSendReceive_IPv6() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| test_setLoopbackModeSendReceive(GOOD_IPv6); |
| } |
| |
| private void test_setLoopbackModeSendReceive(InetAddress group) throws IOException { |
| // Test send receive. |
| final String message = "Hello, world!"; |
| |
| MulticastSocket socket = new MulticastSocket(0); |
| socket.setLoopbackMode(false); // false indicates doing loop back |
| socket.joinGroup(group); |
| |
| // Send the datagram. |
| InetSocketAddress groupAddress = new InetSocketAddress(group, socket.getLocalPort()); |
| DatagramPacket sendDatagram = createSendDatagramPacket(groupAddress, message); |
| socket.send(sendDatagram); |
| |
| // Receive the datagram. |
| DatagramPacket recvDatagram = createReceiveDatagramPacket(); |
| socket.setSoTimeout(5000); // Prevent eternal block in. |
| socket.receive(recvDatagram); |
| String recvMessage = extractMessage(recvDatagram); |
| assertEquals(message, recvMessage); |
| socket.close(); |
| } |
| |
| public void test_setReuseAddressZ() throws Exception { |
| if (!supportsMulticast) { |
| return; |
| } |
| // Test case were we to set ReuseAddress to false. |
| MulticastSocket theSocket1 = new MulticastSocket(null); |
| theSocket1.setReuseAddress(false); |
| |
| MulticastSocket theSocket2 = new MulticastSocket(null); |
| theSocket2.setReuseAddress(false); |
| |
| InetSocketAddress addr = new InetSocketAddress(Inet4Address.getLocalHost(), 0); |
| theSocket1.bind(addr); |
| addr = new InetSocketAddress(Inet4Address.getLocalHost(), theSocket1.getLocalPort()); |
| try { |
| theSocket2.bind(addr); |
| fail("No exception when trying to connect to do duplicate socket bind with re-useaddr" |
| + " set to false"); |
| } catch (BindException expected) { |
| } |
| theSocket1.close(); |
| theSocket2.close(); |
| |
| // Test case were we set it to true. |
| theSocket1 = new MulticastSocket(null); |
| theSocket2 = new MulticastSocket(null); |
| theSocket1.setReuseAddress(true); |
| theSocket2.setReuseAddress(true); |
| addr = new InetSocketAddress(Inet4Address.getLocalHost(), 0); |
| theSocket1.bind(addr); |
| addr = new InetSocketAddress(Inet4Address.getLocalHost(), theSocket1.getLocalPort()); |
| theSocket2.bind(addr); |
| |
| theSocket1.close(); |
| theSocket2.close(); |
| |
| // Test the default case which we expect to be the same on all platforms. |
| theSocket1 = new MulticastSocket(null); |
| theSocket2 = new MulticastSocket(null); |
| addr = new InetSocketAddress(Inet4Address.getLocalHost(), 0); |
| theSocket1.bind(addr); |
| addr = new InetSocketAddress(Inet4Address.getLocalHost(), theSocket1.getLocalPort()); |
| theSocket2.bind(addr); |
| theSocket1.close(); |
| theSocket2.close(); |
| } |
| |
| private static boolean willWorkForMulticast(NetworkInterface iface) throws IOException { |
| return iface.isUp() |
| // Typically loopback interfaces do not support multicast, but we rule them out |
| // explicitly anyway. |
| && !iface.isLoopback() |
| // Point-to-point interfaces are known to cause problems. http://b/23279677 |
| && !iface.isPointToPoint() |
| && iface.supportsMulticast() |
| && iface.getInetAddresses().hasMoreElements(); |
| } |
| |
| private static MulticastSocket createReceivingSocket(int aPort) throws IOException { |
| MulticastSocket ms = new MulticastSocket(aPort); |
| ms.setSoTimeout(2000); |
| return ms; |
| } |
| |
| private static DatagramPacket createReceiveDatagramPacket() { |
| byte[] rbuf = new byte[512]; |
| return new DatagramPacket(rbuf, rbuf.length); |
| } |
| |
| private static DatagramPacket createSendDatagramPacket( |
| InetSocketAddress groupAndPort, String msg) { |
| return new DatagramPacket( |
| msg.getBytes(), msg.length(), groupAndPort.getAddress(), groupAndPort.getPort()); |
| } |
| |
| private static String extractMessage(DatagramPacket rdp) { |
| return new String(rdp.getData(), 0, rdp.getLength()); |
| } |
| } |