MulticastSocketTest.java revision 56b6db3448495b80ccdae1c3df48bd843e030721
1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package org.apache.harmony.luni.tests.java.net;
19
20import java.io.IOException;
21import java.net.BindException;
22import java.net.DatagramPacket;
23import java.net.Inet4Address;
24import java.net.Inet6Address;
25import java.net.InetAddress;
26import java.net.InetSocketAddress;
27import java.net.MulticastSocket;
28import java.net.NetworkInterface;
29import java.net.SocketAddress;
30import java.net.SocketException;
31import java.net.UnknownHostException;
32import java.util.ArrayList;
33import java.util.Enumeration;
34
35import tests.support.Support_PortManager;
36
37public class MulticastSocketTest extends SocketTestCase {
38
39	Thread t;
40
41	MulticastSocket mss;
42
43	MulticastServer server;
44
45	// private member variables used for tests
46	boolean atLeastOneInterface = false;
47
48	boolean atLeastTwoInterfaces = false;
49
50	private NetworkInterface networkInterface1 = null;
51
52	private NetworkInterface networkInterface2 = null;
53
54	private NetworkInterface IPV6networkInterface1 = null;
55
56	static class MulticastServer extends Thread {
57
58		public MulticastSocket ms;
59
60		boolean running = true;
61
62		volatile public byte[] rbuf = new byte[512];
63
64        volatile DatagramPacket rdp = null;
65
66        private InetAddress groupAddr = null;
67        private SocketAddress groupSockAddr = null;
68        private NetworkInterface groupNI = null;
69
70        public void run() {
71			try {
72                byte[] tmpbuf = new byte[512];
73                DatagramPacket tmpPack =
74                        new DatagramPacket(tmpbuf, tmpbuf.length);
75
76                while (running) {
77					try {
78                        ms.receive(tmpPack);
79
80                        System.arraycopy(tmpPack.getData(), 0, rdp.getData(),
81                                rdp.getOffset(), tmpPack.getLength());
82                        rdp.setLength(tmpPack.getLength());
83                        rdp.setAddress(tmpPack.getAddress());
84                        rdp.setPort(tmpPack.getPort());
85                    } catch (java.io.InterruptedIOException e) {
86                        Thread.yield();
87					}
88				}
89			} catch (java.io.IOException e) {
90				System.out.println("Multicast server failed: " + e);
91			} finally {
92				ms.close();
93			}
94		}
95
96		public void stopServer() {
97			running = false;
98            try {
99                if (groupAddr != null) {
100                    ms.leaveGroup(groupAddr);
101                } else if (groupSockAddr != null) {
102                    ms.leaveGroup(groupSockAddr, groupNI);
103                }
104            } catch (IOException e) {}
105        }
106
107        public MulticastServer(InetAddress anAddress, int aPort)
108                throws java.io.IOException {
109            rbuf = new byte[512];
110            rbuf[0] = -1;
111            rdp = new DatagramPacket(rbuf, rbuf.length);
112            ms = new MulticastSocket(aPort);
113            ms.setSoTimeout(2000);
114            groupAddr = anAddress;
115            ms.joinGroup(groupAddr);
116        }
117
118
119        public MulticastServer(SocketAddress anAddress, int aPort,
120				NetworkInterface netInterface) throws java.io.IOException {
121			rbuf = new byte[512];
122			rbuf[0] = -1;
123			rdp = new DatagramPacket(rbuf, rbuf.length);
124			ms = new MulticastSocket(aPort);
125			ms.setSoTimeout(2000);
126            groupSockAddr = anAddress;
127            groupNI = netInterface;
128            ms.joinGroup(groupSockAddr, groupNI);
129		}
130	}
131
132	/**
133	 * @tests java.net.MulticastSocket#MulticastSocket()
134	 */
135	public void test_Constructor() throws IOException {
136		// regression test for 497
137        MulticastSocket s = new MulticastSocket();
138        // regression test for Harmony-1162
139        assertTrue(s.getReuseAddress());
140	}
141
142	/**
143	 * @tests java.net.MulticastSocket#MulticastSocket(int)
144	 */
145	public void test_ConstructorI() throws IOException {
146	    MulticastSocket orig = new MulticastSocket();
147        int port = orig.getLocalPort();
148        orig.close();
149		MulticastSocket dup = null;
150		try {
151			dup = new MulticastSocket(port);
152            // regression test for Harmony-1162
153            assertTrue(dup.getReuseAddress());
154		} catch (IOException e) {
155			fail("duplicate binding not allowed: " + e);
156		}
157		if (dup != null)
158			dup.close();
159	}
160
161	/**
162	 * @tests java.net.MulticastSocket#getInterface()
163	 */
164	public void test_getInterface() throws Exception {
165		// Test for method java.net.InetAddress
166		// java.net.MulticastSocket.getInterface()
167		assertTrue("Used for testing.", true);
168
169		int groupPort = Support_PortManager.getNextPortForUDP();
170
171                if (atLeastOneInterface) {
172                        // validate that we get the expected response when one was not
173                        // set
174                        mss = new MulticastSocket(groupPort);
175                        String preferIPv4StackValue = System
176                                        .getProperty("java.net.preferIPv4Stack");
177                        String preferIPv6AddressesValue = System
178                                        .getProperty("java.net.preferIPv6Addresses");
179                        if (((preferIPv4StackValue == null) || preferIPv4StackValue
180                                        .equalsIgnoreCase("false"))
181                                        && (preferIPv6AddressesValue != null)
182                                        && (preferIPv6AddressesValue.equals("true"))) {
183                                // we expect an IPv6 ANY in this case
184                                assertEquals("inet Address returned when not set",
185                                             InetAddress.getByName("::0"),
186                                             mss.getInterface());
187                        } else {
188                                // we expect an IPv4 ANY in this case
189                                assertEquals("inet Address returned when not set",
190                                             InetAddress.getByName("0.0.0.0"),
191                                             mss.getInterface());
192                        }
193
194                        // validate that we get the expected response when we set via
195                        // setInterface
196                        Enumeration addresses = networkInterface1.getInetAddresses();
197                        if (addresses.hasMoreElements()) {
198                                InetAddress firstAddress = (InetAddress) addresses
199                                                .nextElement();
200                                mss.setInterface(firstAddress);
201                                assertEquals("getNetworkInterface did not return interface set by setInterface",
202                                             firstAddress, mss.getInterface());
203
204                                groupPort = Support_PortManager.getNextPortForUDP();
205                                mss = new MulticastSocket(groupPort);
206                                mss.setNetworkInterface(networkInterface1);
207                                assertEquals("getInterface did not return interface set by setNetworkInterface",
208                                             networkInterface1,
209                                             NetworkInterface.getByInetAddress(mss.getInterface()));
210                        }
211
212                }
213	}
214
215	/**
216	 * @throws IOException
217	 * @tests java.net.MulticastSocket#getNetworkInterface()
218	 */
219	public void test_getNetworkInterface() throws IOException {
220        int groupPort = Support_PortManager.getNextPortForUDP();
221        if (atLeastOneInterface) {
222            // validate that we get the expected response when one was not
223            // set
224            mss = new MulticastSocket(groupPort);
225            NetworkInterface theInterface = mss.getNetworkInterface();
226            assertTrue(
227                    "network interface returned wrong network interface when not set:"
228                            + theInterface, theInterface.getInetAddresses()
229                            .hasMoreElements());
230            InetAddress firstAddress = (InetAddress) theInterface
231                    .getInetAddresses().nextElement();
232            // validate we the first address in the network interface is the
233            // ANY address
234            String preferIPv4StackValue = System
235                    .getProperty("java.net.preferIPv4Stack");
236            String preferIPv6AddressesValue = System
237                    .getProperty("java.net.preferIPv6Addresses");
238            if (((preferIPv4StackValue == null) || preferIPv4StackValue
239                    .equalsIgnoreCase("false"))
240                    && (preferIPv6AddressesValue != null)
241                    && (preferIPv6AddressesValue.equals("true"))) {
242                assertEquals("network interface returned wrong network interface when not set:"
243                             + theInterface,
244                             firstAddress, InetAddress.getByName("::0"));
245
246            } else {
247                assertEquals("network interface returned wrong network interface when not set:"
248                             + theInterface,
249                             InetAddress.getByName("0.0.0.0"),
250                             firstAddress);
251            }
252
253            mss.setNetworkInterface(networkInterface1);
254            assertEquals("getNetworkInterface did not return interface set by setNeworkInterface",
255                         networkInterface1, mss.getNetworkInterface());
256
257            if (atLeastTwoInterfaces) {
258                mss.setNetworkInterface(networkInterface2);
259                assertEquals("getNetworkInterface did not return network interface set by second setNetworkInterface call",
260                             networkInterface2, mss.getNetworkInterface());
261            }
262
263            groupPort = Support_PortManager.getNextPortForUDP();
264            mss = new MulticastSocket(groupPort);
265            if (IPV6networkInterface1 != null) {
266                mss.setNetworkInterface(IPV6networkInterface1);
267                assertEquals("getNetworkInterface did not return interface set by setNeworkInterface",
268                             IPV6networkInterface1,
269                             mss.getNetworkInterface());
270            }
271
272            // validate that we get the expected response when we set via
273            // setInterface
274            groupPort = Support_PortManager.getNextPortForUDP();
275            mss = new MulticastSocket(groupPort);
276            Enumeration addresses = networkInterface1.getInetAddresses();
277            if (addresses.hasMoreElements()) {
278                firstAddress = (InetAddress) addresses.nextElement();
279                mss.setInterface(firstAddress);
280                assertEquals("getNetworkInterface did not return interface set by setInterface",
281                             networkInterface1,
282                             mss.getNetworkInterface());
283            }
284        }
285    }
286
287	/**
288	 * @tests java.net.MulticastSocket#getTimeToLive()
289	 */
290	public void test_getTimeToLive() throws Exception {
291			mss = new MulticastSocket();
292			mss.setTimeToLive(120);
293			assertEquals("Returned incorrect 1st TTL",
294                                     120, mss.getTimeToLive());
295			mss.setTimeToLive(220);
296			assertEquals("Returned incorrect 2nd TTL",
297                                     220, mss.getTimeToLive());
298			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
299	}
300
301	/**
302	 * @tests java.net.MulticastSocket#getTTL()
303	 */
304	public void test_getTTL() throws Exception {
305		// Test for method byte java.net.MulticastSocket.getTTL()
306
307			mss = new MulticastSocket();
308			mss.setTTL((byte) 120);
309			assertEquals("Returned incorrect TTL",
310                                     120, mss.getTTL());
311			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
312	}
313
314	/**
315	 * @tests java.net.MulticastSocket#joinGroup(java.net.InetAddress)
316	 */
317	public void test_joinGroupLjava_net_InetAddress() throws Exception {
318		// Test for method void
319		// java.net.MulticastSocket.joinGroup(java.net.InetAddress)
320                String msg = null;
321		InetAddress group = null;
322		int[] ports = Support_PortManager.getNextPortsForUDP(2);
323		int groupPort = ports[0];
324                group = InetAddress.getByName("224.0.0.3");
325                server = new MulticastServer(group, groupPort);
326                server.start();
327                Thread.sleep(1000);
328                msg = "Hello World";
329                mss = new MulticastSocket(ports[1]);
330                DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg
331                                .length(), group, groupPort);
332                mss.send(sdp, (byte) 10);
333                Thread.sleep(1000);
334
335                assertEquals("Group member did not recv data",
336                             msg,
337                             new String(server.rdp.getData(), 0, server.rdp.getLength()));
338	}
339
340	/**
341	 * @throws IOException
342	 * @throws InterruptedException
343	 * @tests java.net.MulticastSocket#joinGroup(java.net.SocketAddress,java.net.NetworkInterface)
344	 */
345	public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface() throws IOException, InterruptedException {
346		String msg = null;
347		InetAddress group = null;
348		SocketAddress groupSockAddr = null;
349		int[] ports = Support_PortManager.getNextPortsForUDP(2);
350		int groupPort = ports[0];
351		int serverPort = ports[1];
352
353        Enumeration<NetworkInterface> theInterfaces = NetworkInterface.getNetworkInterfaces();
354
355        // first validate that we handle a null group ok
356        mss = new MulticastSocket(groupPort);
357        try {
358            mss.joinGroup(null, null);
359            fail("Did not get exception when group was null");
360        } catch (IllegalArgumentException e) {
361        }
362
363        // now validate we get the expected error if the address specified
364        // is not a multicast group
365        try {
366            groupSockAddr = new InetSocketAddress(InetAddress
367                    .getByName("255.255.255.255"), groupPort);
368            mss.joinGroup(groupSockAddr, null);
369            fail("Did not get exception when group is not a multicast address");
370        } catch (IOException e) {
371        }
372
373        // now try to join a group if we are not authorized
374        // set the security manager that will make the first address not
375        // visible
376        group = InetAddress.getByName("224.0.0.3");
377        groupSockAddr = new InetSocketAddress(group, groupPort);
378        mss.joinGroup(groupSockAddr, null);
379
380        if (atLeastOneInterface) {
381            // now validate that we can properly join a group with a null
382            // network interface
383            ports = Support_PortManager.getNextPortsForUDP(2);
384            groupPort = ports[0];
385            serverPort = ports[1];
386            mss = new MulticastSocket(groupPort);
387            mss.joinGroup(groupSockAddr, null);
388            mss.setTimeToLive(2);
389            Thread.sleep(1000);
390
391            // set up the server and join the group on networkInterface1
392            group = InetAddress.getByName("224.0.0.3");
393            groupSockAddr = new InetSocketAddress(group, groupPort);
394            server = new MulticastServer(groupSockAddr, serverPort,
395                    networkInterface1);
396            server.start();
397            Thread.sleep(1000);
398            msg = "Hello World";
399            DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg
400                    .length(), group, serverPort);
401            mss.setTimeToLive(2);
402            mss.send(sdp);
403            Thread.sleep(1000);
404            // now vaildate that we received the data as expected
405            assertEquals("Group member did not recv data",
406                         msg,
407                         new String(server.rdp.getData(), 0, server.rdp.getLength()));
408            server.stopServer();
409
410            // now validate that we handled the case were we join a
411            // different multicast address.
412            // verify we do not receive the data
413            ports = Support_PortManager.getNextPortsForUDP(2);
414            serverPort = ports[0];
415            server = new MulticastServer(groupSockAddr, serverPort,
416                    networkInterface1);
417            server.start();
418            Thread.sleep(1000);
419
420            groupPort = ports[1];
421            mss = new MulticastSocket(groupPort);
422            InetAddress group2 = InetAddress.getByName("224.0.0.4");
423            mss.setTimeToLive(10);
424            msg = "Hello World - Different Group";
425            sdp = new DatagramPacket(msg.getBytes(), msg.length(), group2,
426                    serverPort);
427            mss.send(sdp);
428            Thread.sleep(1000);
429            assertFalse(
430                    "Group member received data when sent on different group: ",
431                    new String(server.rdp.getData(), 0, server.rdp.getLength())
432                            .equals(msg));
433            server.stopServer();
434
435            // if there is more than one network interface then check that
436            // we can join on specific interfaces and that we only receive
437            // if data is received on that interface
438            if (atLeastTwoInterfaces) {
439                // set up server on first interfaces
440                NetworkInterface loopbackInterface = NetworkInterface
441                        .getByInetAddress(InetAddress.getByName("127.0.0.1"));
442
443                boolean anyLoop = networkInterface1.equals(loopbackInterface) || networkInterface2.equals(loopbackInterface);
444
445                ArrayList<NetworkInterface> realInterfaces = new ArrayList<NetworkInterface>();
446                theInterfaces = NetworkInterface.getNetworkInterfaces();
447                while (theInterfaces.hasMoreElements()) {
448                    NetworkInterface thisInterface = (NetworkInterface) theInterfaces.nextElement();
449                    if (thisInterface.getInetAddresses().hasMoreElements()){
450                        realInterfaces.add(thisInterface);
451                    }
452                }
453
454                for (int i = 0; i < realInterfaces.size(); i++) {
455                    final int SECOND = 1;
456                    NetworkInterface thisInterface = realInterfaces.get(i);
457
458                        // get the first address on the interface
459
460                        // start server which is joined to the group and has
461                        // only asked for packets on this interface
462                        Enumeration<InetAddress> addresses = thisInterface.getInetAddresses();
463
464                        NetworkInterface sendingInterface = null;
465                        if (addresses.hasMoreElements()) {
466                            InetAddress firstAddress = (InetAddress) addresses.nextElement();
467                            if (firstAddress instanceof Inet4Address) {
468                                group = InetAddress.getByName("224.0.0.4");
469                                if (anyLoop) {
470                                    if (networkInterface1.equals(loopbackInterface)) {
471                                        sendingInterface = networkInterface2;
472                                    } else {
473                                        sendingInterface = networkInterface1;
474                                    }
475                                } else {
476                                    if(i == SECOND){
477                                        sendingInterface = networkInterface2;
478                                    } else {
479                                        sendingInterface = networkInterface1;
480                                }
481                               }
482                            } else {
483                                // if this interface only seems to support
484                                // IPV6 addresses
485                                group = InetAddress
486                                        .getByName("FF01:0:0:0:0:0:2:8001");
487                                sendingInterface = IPV6networkInterface1;
488                            }
489                        }
490
491                        ports = Support_PortManager.getNextPortsForUDP(2);
492                        serverPort = ports[0];
493                        groupPort = ports[1];
494                        groupSockAddr = new InetSocketAddress(group, serverPort);
495                        server = new MulticastServer(groupSockAddr, serverPort,
496                                thisInterface);
497                        server.start();
498                        Thread.sleep(1000);
499
500                        // Now send out a package on interface
501                        // networkInterface 1. We should
502                        // only see the packet if we send it on interface 1
503                        mss = new MulticastSocket(groupPort);
504                        mss.setNetworkInterface(sendingInterface);
505                        msg = "Hello World - Again" + thisInterface.getName();
506                        sdp = new DatagramPacket(msg.getBytes(), msg.length(),
507                                group, serverPort);
508                        mss.send(sdp);
509                        Thread.sleep(1000);
510                        if (thisInterface.equals(sendingInterface)) {
511                            assertEquals("Group member did not recv data when bound on specific interface",
512                                         msg,
513                                         new String(server.rdp.getData(), 0, server.rdp.getLength()));
514                        } else {
515                            assertFalse(
516                                    "Group member received data on other interface when only asked for it on one interface: ",
517                                    new String(server.rdp.getData(), 0,
518                                            server.rdp.getLength()).equals(msg));
519                        }
520
521                        server.stopServer();
522                    }
523
524
525                // validate that we can join the same address on two
526                // different interfaces but not on the same interface
527                groupPort = Support_PortManager.getNextPortForUDP();
528                mss = new MulticastSocket(groupPort);
529                mss.joinGroup(groupSockAddr, networkInterface1);
530                mss.joinGroup(groupSockAddr, networkInterface2);
531                try {
532                    mss.joinGroup(groupSockAddr, networkInterface1);
533                    fail("Did not get expected exception when joining for second time on same interface");
534                } catch (IOException e) {
535                }
536            }
537        }
538	}
539
540	/**
541	 * @tests java.net.MulticastSocket#leaveGroup(java.net.InetAddress)
542	 */
543	public void test_leaveGroupLjava_net_InetAddress() {
544		// Test for method void
545		// java.net.MulticastSocket.leaveGroup(java.net.InetAddress)
546		String msg = null;
547		boolean except = false;
548		InetAddress group = null;
549		int[] ports = Support_PortManager.getNextPortsForUDP(2);
550		int groupPort = ports[0];
551
552		try {
553			group = InetAddress.getByName("224.0.0.3");
554			msg = "Hello World";
555			mss = new MulticastSocket(ports[1]);
556			DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg
557					.length(), group, groupPort);
558			mss.send(sdp, (byte) 10);
559			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
560		} catch (Exception e) {
561			handleException(e, SO_MULTICAST);
562		}
563		try {
564			// Try to leave s group that mss is not a member of
565			mss.leaveGroup(group);
566		} catch (java.io.IOException e) {
567			// Correct
568			except = true;
569		}
570		assertTrue("Failed to throw exception leaving non-member group", except);
571	}
572
573	/**
574	 * @tests java.net.MulticastSocket#leaveGroup(java.net.SocketAddress,java.net.NetworkInterface)
575	 */
576	public void test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface() throws Exception {
577		String msg = null;
578		InetAddress group = null;
579		int groupPort = Support_PortManager.getNextPortForUDP();
580		SocketAddress groupSockAddr = null;
581		SocketAddress groupSockAddr2 = null;
582
583                Enumeration theInterfaces = NetworkInterface.getNetworkInterfaces();
584
585                // first validate that we handle a null group ok
586                mss = new MulticastSocket(groupPort);
587                try {
588                        mss.leaveGroup(null, null);
589                        fail("Did not get exception when group was null");
590                } catch (IllegalArgumentException e) {
591                }
592
593                // now validate we get the expected error if the address specified
594                // is not a multicast group
595                try {
596                        group = InetAddress.getByName("255.255.255.255");
597                        groupSockAddr = new InetSocketAddress(group, groupPort);
598                        mss.leaveGroup(groupSockAddr, null);
599                        fail("Did not get exception when group is not a multicast address");
600                } catch (IOException e) {
601                }
602
603                        group = InetAddress.getByName("224.0.0.3");
604                        groupSockAddr = new InetSocketAddress(group, groupPort);
605                        mss.leaveGroup(groupSockAddr, null);
606
607                if (atLeastOneInterface) {
608
609                        // now test that we can join and leave a group successfully
610                        groupPort = Support_PortManager.getNextPortForUDP();
611                        mss = new MulticastSocket(groupPort);
612                        groupSockAddr = new InetSocketAddress(group, groupPort);
613                        mss.joinGroup(groupSockAddr, null);
614                        mss.leaveGroup(groupSockAddr, null);
615                        try {
616                                mss.leaveGroup(groupSockAddr, null);
617                                fail(
618                                                "Did not get exception when trying to leave group that was allready left");
619                        } catch (IOException e) {
620                        }
621
622                        InetAddress group2 = InetAddress.getByName("224.0.0.4");
623                        groupSockAddr2 = new InetSocketAddress(group2, groupPort);
624                        mss.joinGroup(groupSockAddr, networkInterface1);
625                        try {
626                                mss.leaveGroup(groupSockAddr2, networkInterface1);
627                                fail(
628                                                "Did not get exception when trying to leave group that was never joined");
629                        } catch (IOException e) {
630                        }
631
632                        mss.leaveGroup(groupSockAddr, networkInterface1);
633                        if (atLeastTwoInterfaces) {
634                                mss.joinGroup(groupSockAddr, networkInterface1);
635                                try {
636                                        mss.leaveGroup(groupSockAddr, networkInterface2);
637                                        fail(
638                                                        "Did not get exception when trying to leave group on wrong interface joined on ["
639                                                                        + networkInterface1
640                                                                        + "] left on ["
641                                                                        + networkInterface2 + "]");
642                                } catch (IOException e) {
643                                }
644                        }
645                }
646	}
647
648	/**
649	 * @tests java.net.MulticastSocket#send(java.net.DatagramPacket, byte)
650	 */
651	public void test_sendLjava_net_DatagramPacketB() {
652		// Test for method void
653		// java.net.MulticastSocket.send(java.net.DatagramPacket, byte)
654
655		String msg = "Hello World";
656		InetAddress group = null;
657		int[] ports = Support_PortManager.getNextPortsForUDP(2);
658		int groupPort = ports[0];
659
660		try {
661			group = InetAddress.getByName("224.0.0.3");
662			mss = new MulticastSocket(ports[1]);
663			server = new MulticastServer(group, groupPort);
664			server.start();
665			Thread.sleep(200);
666			DatagramPacket sdp = new DatagramPacket(msg.getBytes(), msg
667					.length(), group, groupPort);
668			mss.send(sdp, (byte) 10);
669			Thread.sleep(1000);
670			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
671		} catch (Exception e) {
672			handleException(e, SO_MULTICAST);
673			try {
674				mss.close();
675			} catch (Exception ex) {
676			}
677			;
678			return;
679		}
680		mss.close();
681		byte[] data = server.rdp.getData();
682		int length = server.rdp.getLength();
683		assertEquals("Failed to send data. Received " + length,
684                             msg, new String(data, 0, length));
685	}
686
687	/**
688	 * @tests java.net.MulticastSocket#setInterface(java.net.InetAddress)
689	 */
690	public void test_setInterfaceLjava_net_InetAddress() throws UnknownHostException {
691		// Test for method void
692		// java.net.MulticastSocket.setInterface(java.net.InetAddress)
693		// Note that the machine is not multi-homed
694
695		try {
696			mss = new MulticastSocket();
697			mss.setInterface(InetAddress.getLocalHost());
698			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST_INTERFACE);
699		} catch (Exception e) {
700			handleException(e, SO_MULTICAST_INTERFACE);
701			return;
702		}
703		try {
704			InetAddress theInterface = mss.getInterface();
705			// under IPV6 we are not guarrenteed to get the same address back as
706			// the address, all we should be guaranteed is that we get an
707			// address on the same interface
708			if (theInterface instanceof Inet6Address) {
709				assertTrue(
710						"Failed to return correct interface IPV6",
711						NetworkInterface
712								.getByInetAddress(mss.getInterface())
713								.equals(
714										NetworkInterface
715												.getByInetAddress(theInterface)));
716			} else {
717				assertTrue("Failed to return correct interface IPV4 got:"
718						+ mss.getInterface() + " excpeted: "
719						+ InetAddress.getLocalHost(), mss.getInterface()
720						.equals(InetAddress.getLocalHost()));
721			}
722			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
723		} catch (SocketException e) {
724			handleException(e, SO_MULTICAST);
725		}
726
727		// Regression test for Harmony-2410
728		try {
729			mss = new MulticastSocket();
730			mss.setInterface(InetAddress.getByName("224.0.0.5"));
731		} catch (SocketException se) {
732			// expected
733		} catch (IOException ioe) {
734			handleException(ioe, SO_MULTICAST_INTERFACE);
735			return;
736		}
737	}
738
739	/**
740	 * @throws IOException
741	 * @throws InterruptedException
742	 * @tests java.net.MulticastSocket#setNetworkInterface(java.net.NetworkInterface)
743	 */
744	public void test_setNetworkInterfaceLjava_net_NetworkInterface() throws IOException, InterruptedException {
745		String msg = null;
746		InetAddress group = null;
747		int[] ports = Support_PortManager.getNextPortsForUDP(2);
748		int groupPort = ports[0];
749		int serverPort = ports[1];
750		if (atLeastOneInterface) {
751            // validate that null interface is handled ok
752            mss = new MulticastSocket(groupPort);
753
754            // this should through a socket exception to be compatible
755            try {
756                mss.setNetworkInterface(null);
757                fail("No socket exception when we set then network interface with NULL");
758            } catch (SocketException ex) {
759            }
760
761            // validate that we can get and set the interface
762            groupPort = Support_PortManager.getNextPortForUDP();
763            mss = new MulticastSocket(groupPort);
764            mss.setNetworkInterface(networkInterface1);
765            assertEquals("Interface did not seem to be set by setNeworkInterface",
766                         networkInterface1, mss.getNetworkInterface());
767
768            // set up the server and join the group
769            group = InetAddress.getByName("224.0.0.3");
770
771            Enumeration theInterfaces = NetworkInterface.getNetworkInterfaces();
772            while (theInterfaces.hasMoreElements()) {
773                NetworkInterface thisInterface = (NetworkInterface) theInterfaces
774                        .nextElement();
775                if (thisInterface.getInetAddresses().hasMoreElements()) {
776                    if ((!((InetAddress) thisInterface.getInetAddresses().nextElement()).isLoopbackAddress())) {
777                        ports = Support_PortManager.getNextPortsForUDP(2);
778                        serverPort = ports[0];
779                        server = new MulticastServer(group, serverPort);
780                        server.start();
781                        // give the server some time to start up
782                        Thread.sleep(1000);
783
784                        // Send the packets on a particular interface. The
785                        // source address in the received packet
786                        // should be one of the addresses for the interface
787                        // set
788                        groupPort = ports[1];
789                        mss = new MulticastSocket(groupPort);
790                        mss.setNetworkInterface(thisInterface);
791                        msg = thisInterface.getName();
792                        byte theBytes[] = msg.getBytes();
793                        DatagramPacket sdp = new DatagramPacket(theBytes,
794                                theBytes.length, group, serverPort);
795                        mss.send(sdp);
796                        Thread.sleep(1000);
797                        String receivedMessage = new String(server.rdp
798                                .getData(), 0, server.rdp.getLength());
799                        assertEquals("Group member did not recv data sent on a specific interface",
800                                     msg, receivedMessage);
801                        // stop the server
802                        server.stopServer();
803                    }
804                }
805            }
806        }
807	}
808
809	/**
810	 * @tests java.net.MulticastSocket#setTimeToLive(int)
811	 */
812	public void test_setTimeToLiveI() {
813		try {
814			mss = new MulticastSocket();
815			mss.setTimeToLive(120);
816			assertEquals("Returned incorrect 1st TTL",
817                                     120, mss.getTimeToLive());
818			mss.setTimeToLive(220);
819			assertEquals("Returned incorrect 2nd TTL",
820                                     220, mss.getTimeToLive());
821			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
822		} catch (Exception e) {
823			handleException(e, SO_MULTICAST);
824		}
825	}
826
827	/**
828	 * @tests java.net.MulticastSocket#setTTL(byte)
829	 */
830	public void test_setTTLB() {
831		// Test for method void java.net.MulticastSocket.setTTL(byte)
832		try {
833			mss = new MulticastSocket();
834			mss.setTTL((byte) 120);
835			assertEquals("Failed to set TTL", 120, mss.getTTL());
836			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_MULTICAST);
837		} catch (Exception e) {
838			handleException(e, SO_MULTICAST);
839		}
840	}
841
842	/**
843	 * @tests java.net.MulticastSocket#MulticastSocket(java.net.SocketAddress)
844	 */
845	public void test_ConstructorLjava_net_SocketAddress() throws Exception {
846		MulticastSocket ms = new MulticastSocket((SocketAddress) null);
847        assertTrue("should not be bound", !ms.isBound() && !ms.isClosed()
848                && !ms.isConnected());
849        ms.bind(new InetSocketAddress(InetAddress.getLocalHost(),
850                Support_PortManager.getNextPortForUDP()));
851        assertTrue("should be bound", ms.isBound() && !ms.isClosed()
852                && !ms.isConnected());
853        ms.close();
854        assertTrue("should be closed", ms.isClosed());
855        ms = new MulticastSocket(new InetSocketAddress(InetAddress
856                .getLocalHost(), Support_PortManager.getNextPortForUDP()));
857        assertTrue("should be bound", ms.isBound() && !ms.isClosed()
858                && !ms.isConnected());
859        ms.close();
860        assertTrue("should be closed", ms.isClosed());
861        ms = new MulticastSocket(new InetSocketAddress("localhost",
862                Support_PortManager.getNextPortForUDP()));
863        assertTrue("should be bound", ms.isBound() && !ms.isClosed()
864                && !ms.isConnected());
865        ms.close();
866        assertTrue("should be closed", ms.isClosed());
867        boolean exception = false;
868        try {
869            ms = new MulticastSocket(new InetSocketAddress("unresolvedname",
870                    Support_PortManager.getNextPortForUDP()));
871        } catch (IOException e) {
872            exception = true;
873        }
874        assertTrue("Expected IOException", exception);
875
876        // regression test for Harmony-1162
877        InetSocketAddress addr = new InetSocketAddress("0.0.0.0", 0);
878        MulticastSocket s = new MulticastSocket(addr);
879        assertTrue(s.getReuseAddress());
880	}
881
882	/**
883	 * @tests java.net.MulticastSocket#getLoopbackMode()
884	 */
885	public void test_getLoopbackMode() {
886		try {
887			MulticastSocket ms = new MulticastSocket((SocketAddress) null);
888			assertTrue("should not be bound", !ms.isBound() && !ms.isClosed()
889					&& !ms.isConnected());
890			ms.getLoopbackMode();
891			assertTrue("should not be bound", !ms.isBound() && !ms.isClosed()
892					&& !ms.isConnected());
893			ms.close();
894			assertTrue("should be closed", ms.isClosed());
895			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_USELOOPBACK);
896		} catch (IOException e) {
897			handleException(e, SO_USELOOPBACK);
898		}
899	}
900
901	/**
902	 * @tests java.net.MulticastSocket#setLoopbackMode(boolean)
903	 */
904	public void test_setLoopbackModeZ() {
905		try {
906			MulticastSocket ms = new MulticastSocket();
907			ms.setLoopbackMode(true);
908			assertTrue("loopback should be true", ms.getLoopbackMode());
909			ms.setLoopbackMode(false);
910			assertTrue("loopback should be false", !ms.getLoopbackMode());
911			ms.close();
912			assertTrue("should be closed", ms.isClosed());
913			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_USELOOPBACK);
914		} catch (IOException e) {
915			handleException(e, SO_USELOOPBACK);
916		}
917	}
918
919    /**
920     * @tests java.net.MulticastSocket#setLoopbackMode(boolean)
921     */
922    public void test_setLoopbackModeSendReceive() throws IOException{
923        final String ADDRESS = "224.1.2.3";
924        final int PORT = Support_PortManager.getNextPortForUDP();
925        final String message = "Hello, world!";
926
927        // test send receive
928        MulticastSocket socket = null;
929        try {
930            // open a multicast socket
931            socket = new MulticastSocket(PORT);
932            socket.setLoopbackMode(false); // false indecates doing loop back
933            socket.joinGroup(InetAddress.getByName(ADDRESS));
934
935            // send the datagram
936            byte[] sendData = message.getBytes();
937            DatagramPacket sendDatagram = new DatagramPacket(sendData, 0,
938                    sendData.length, new InetSocketAddress(InetAddress
939                            .getByName(ADDRESS), PORT));
940            socket.send(sendDatagram);
941
942            // receive the datagram
943            byte[] recvData = new byte[100];
944            DatagramPacket recvDatagram = new DatagramPacket(recvData,
945                    recvData.length);
946            socket.setSoTimeout(5000); // prevent eternal block in
947            // socket.receive()
948            socket.receive(recvDatagram);
949            String recvMessage = new String(recvData, 0, recvDatagram
950                    .getLength());
951            assertEquals(message, recvMessage);
952        }finally {
953            if (socket != null)
954                socket.close();
955        }
956    }
957
958
959	/**
960	 * @tests java.net.MulticastSocket#setReuseAddress(boolean)
961	 */
962	public void test_setReuseAddressZ() throws Exception {
963		try {
964			// test case were we set it to false
965			MulticastSocket theSocket1 = null;
966			MulticastSocket theSocket2 = null;
967			try {
968				InetSocketAddress theAddress = new InetSocketAddress(
969						InetAddress.getLocalHost(), Support_PortManager
970								.getNextPortForUDP());
971				theSocket1 = new MulticastSocket(null);
972				theSocket2 = new MulticastSocket(null);
973				theSocket1.setReuseAddress(false);
974				theSocket2.setReuseAddress(false);
975				theSocket1.bind(theAddress);
976				theSocket2.bind(theAddress);
977				fail(
978						"No exception when trying to connect to do duplicate socket bind with re-useaddr set to false");
979			} catch (BindException e) {
980
981			}
982			if (theSocket1 != null)
983				theSocket1.close();
984			if (theSocket2 != null)
985				theSocket2.close();
986
987			// test case were we set it to true
988                        InetSocketAddress theAddress = new InetSocketAddress(
989                                        InetAddress.getLocalHost(), Support_PortManager
990                                                        .getNextPortForUDP());
991                        theSocket1 = new MulticastSocket(null);
992                        theSocket2 = new MulticastSocket(null);
993                        theSocket1.setReuseAddress(true);
994                        theSocket2.setReuseAddress(true);
995                        theSocket1.bind(theAddress);
996                        theSocket2.bind(theAddress);
997
998                        if (theSocket1 != null)
999				theSocket1.close();
1000			if (theSocket2 != null)
1001				theSocket2.close();
1002
1003			// test the default case which we expect to be
1004			// the same on all platforms
1005                        theAddress =
1006                            new InetSocketAddress(
1007                                    InetAddress.getLocalHost(),
1008                                    Support_PortManager.getNextPortForUDP());
1009                        theSocket1 = new MulticastSocket(null);
1010                        theSocket2 = new MulticastSocket(null);
1011                        theSocket1.bind(theAddress);
1012                        theSocket2.bind(theAddress);
1013			if (theSocket1 != null)
1014				theSocket1.close();
1015			if (theSocket2 != null)
1016				theSocket2.close();
1017			ensureExceptionThrownIfOptionIsUnsupportedOnOS(SO_REUSEADDR);
1018		} catch (Exception e) {
1019			handleException(e, SO_REUSEADDR);
1020		}
1021	}
1022
1023	/**
1024	 * Sets up the fixture, for example, open a network connection. This method
1025	 * is called before a test is executed.
1026	 */
1027	protected void setUp() {
1028
1029		Enumeration theInterfaces = null;
1030		try {
1031			theInterfaces = NetworkInterface.getNetworkInterfaces();
1032		} catch (Exception e) {
1033		}
1034
1035		// only consider interfaces that have addresses associated with them.
1036		// Otherwise tests don't work so well
1037		if (theInterfaces != null) {
1038
1039			atLeastOneInterface = false;
1040			while (theInterfaces.hasMoreElements()
1041                    && (atLeastOneInterface == false)) {
1042                networkInterface1 = (NetworkInterface) theInterfaces
1043                        .nextElement();
1044                if (networkInterface1.getInetAddresses().hasMoreElements()) {
1045                    atLeastOneInterface = true;
1046                }
1047            }
1048
1049			atLeastTwoInterfaces = false;
1050			if (theInterfaces.hasMoreElements()) {
1051                while (theInterfaces.hasMoreElements()
1052                        && (atLeastTwoInterfaces == false)) {
1053                    networkInterface2 = (NetworkInterface) theInterfaces
1054                            .nextElement();
1055                    if (networkInterface2.getInetAddresses().hasMoreElements()) {
1056                        atLeastTwoInterfaces = true;
1057                    }
1058                }
1059            }
1060
1061			Enumeration addresses;
1062
1063			// first the first interface that supports IPV6 if one exists
1064			try {
1065				theInterfaces = NetworkInterface.getNetworkInterfaces();
1066			} catch (Exception e) {
1067			}
1068			boolean found = false;
1069			while (theInterfaces.hasMoreElements() && !found) {
1070				NetworkInterface nextInterface = (NetworkInterface) theInterfaces
1071						.nextElement();
1072				addresses = nextInterface.getInetAddresses();
1073				if (addresses.hasMoreElements()) {
1074					while (addresses.hasMoreElements()) {
1075						InetAddress nextAddress = (InetAddress) addresses
1076								.nextElement();
1077						if (nextAddress instanceof Inet6Address) {
1078							IPV6networkInterface1 = nextInterface;
1079							found = true;
1080							break;
1081						}
1082					}
1083				}
1084			}
1085		}
1086	}
1087
1088	/**
1089	 * Tears down the fixture, for example, close a network connection. This
1090	 * method is called after a test is executed.
1091	 */
1092	protected void tearDown() {
1093
1094		if (t != null)
1095			t.interrupt();
1096		if (mss != null)
1097			mss.close();
1098		if (server != null)
1099			server.stopServer();
1100	}
1101}
1102