jdk/test/java/nio/channels/DatagramChannel/MulticastSendReceiveTests.java
changeset 1152 29d6145d1097
child 3424 8f6c0145dc8f
equal deleted inserted replaced
1151:4070cecdb99d 1152:29d6145d1097
       
     1 /*
       
     2  * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    21  * have any questions.
       
    22  */
       
    23 
       
    24 /* @test
       
    25  * @bug 4527345
       
    26  * @summary Unit test for DatagramChannel's multicast support
       
    27  * @build MulticastSendReceiveTests NetworkConfiguration
       
    28  */
       
    29 
       
    30 import java.nio.ByteBuffer;
       
    31 import java.nio.channels.*;
       
    32 import java.net.*;
       
    33 import java.util.*;
       
    34 import java.io.IOException;
       
    35 
       
    36 public class MulticastSendReceiveTests {
       
    37 
       
    38     static Random rand = new Random();
       
    39 
       
    40     /**
       
    41      * Send datagram from given local address to given multicast
       
    42      * group.
       
    43      */
       
    44     static int sendDatagram(InetAddress local,
       
    45                             NetworkInterface nif,
       
    46                             InetAddress group,
       
    47                             int port)
       
    48         throws IOException
       
    49     {
       
    50         ProtocolFamily family = (group instanceof Inet6Address) ?
       
    51             StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
       
    52         DatagramChannel dc = DatagramChannel.open(family)
       
    53             .bind(new InetSocketAddress(local, 0))
       
    54             .setOption(StandardSocketOption.IP_MULTICAST_IF, nif);
       
    55         int id = rand.nextInt();
       
    56         byte[] msg = Integer.toString(id).getBytes("UTF-8");
       
    57         ByteBuffer buf = ByteBuffer.wrap(msg);
       
    58         System.out.format("Send message from %s -> group %s (id=0x%x)\n",
       
    59             local.getHostAddress(), group.getHostAddress(), id);
       
    60         dc.send(buf, new InetSocketAddress(group, port));
       
    61         dc.close();
       
    62         return id;
       
    63     }
       
    64 
       
    65     /**
       
    66      * Wait (with timeout) for datagram.
       
    67      *
       
    68      * @param   expectedSender - expected sender address, or
       
    69      *                           null if no datagram expected
       
    70      * @param   id - expected id of datagram
       
    71      */
       
    72     static void receiveDatagram(DatagramChannel dc,
       
    73                                 InetAddress expectedSender,
       
    74                                 int id)
       
    75         throws IOException
       
    76     {
       
    77         Selector sel = Selector.open();
       
    78         dc.configureBlocking(false);
       
    79         dc.register(sel, SelectionKey.OP_READ);
       
    80         ByteBuffer buf = ByteBuffer.allocateDirect(100);
       
    81 
       
    82         try {
       
    83             for (;;) {
       
    84                 System.out.println("Waiting to receive message");
       
    85                 sel.select(5*1000);
       
    86                 SocketAddress sa = dc.receive(buf);
       
    87 
       
    88                 // no datagram received
       
    89                 if (sa == null) {
       
    90                     if (expectedSender != null) {
       
    91                         throw new RuntimeException("Expected message not recieved");
       
    92                     }
       
    93                     System.out.println("No message received (correct)");
       
    94                     return;
       
    95                 }
       
    96 
       
    97                 // datagram received
       
    98 
       
    99                 InetAddress sender = ((InetSocketAddress)sa).getAddress();
       
   100                 buf.flip();
       
   101                 byte[] bytes = new byte[buf.remaining()];
       
   102                 buf.get(bytes);
       
   103                 int receivedId = Integer.parseInt(new String(bytes));
       
   104 
       
   105                 System.out.format("Received message from %s (id=0x%x)\n",
       
   106                     sender, receivedId);
       
   107 
       
   108                 if (expectedSender == null) {
       
   109                     if (receivedId == id)
       
   110                         throw new RuntimeException("Message not expected");
       
   111                     System.out.println("Message ignored (has wrong id)");
       
   112                 } else {
       
   113                     if (sender.equals(expectedSender)) {
       
   114                         System.out.println("Message expected");
       
   115                         return;
       
   116                     }
       
   117                     System.out.println("Message ignored (wrong sender)");
       
   118                 }
       
   119 
       
   120                 sel.selectedKeys().clear();
       
   121                 buf.rewind();
       
   122             }
       
   123         } finally {
       
   124             sel.close();
       
   125         }
       
   126     }
       
   127 
       
   128 
       
   129     /**
       
   130      * Exercise multicast send/receive on given group/interface
       
   131      */
       
   132     static void test(NetworkInterface nif, InetAddress group, InetAddress source)
       
   133         throws IOException
       
   134     {
       
   135         ProtocolFamily family = (group instanceof Inet6Address) ?
       
   136             StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
       
   137         System.out.format("create channel to %s socket\n", family.name());
       
   138         DatagramChannel dc = DatagramChannel.open(family)
       
   139             .setOption(StandardSocketOption.SO_REUSEADDR, true)
       
   140             .bind(new InetSocketAddress(0));
       
   141 
       
   142         // join group
       
   143         System.out.format("join %s @ %s\n", group.getHostAddress(),
       
   144             nif.getName());
       
   145         MembershipKey key = dc.join(group, nif);
       
   146 
       
   147         // send message to group
       
   148         int port = ((InetSocketAddress)dc.getLocalAddress()).getPort();
       
   149         int id = sendDatagram(source, nif, group, port);
       
   150 
       
   151         // receive message and check id matches
       
   152         receiveDatagram(dc, source, id);
       
   153 
       
   154         // exclude-mode filtering
       
   155 
       
   156         try {
       
   157             System.out.format("block %s\n", source.getHostAddress());
       
   158 
       
   159             // may throw UOE
       
   160             key.block(source);
       
   161             id = sendDatagram(source, nif, group, port);
       
   162             receiveDatagram(dc, null, id);
       
   163 
       
   164             // unblock source, send message, message should be received
       
   165             System.out.format("unblock %s\n", source.getHostAddress());
       
   166             key.unblock(source);
       
   167             id = sendDatagram(source, nif, group, port);
       
   168             receiveDatagram(dc, source, id);
       
   169         } catch (UnsupportedOperationException x) {
       
   170             System.out.println("Exclude-mode filtering not supported!");
       
   171         }
       
   172 
       
   173         key.drop();
       
   174 
       
   175         // include-mode filtering
       
   176 
       
   177         InetAddress bogus = (group instanceof Inet6Address) ?
       
   178             InetAddress.getByName("fe80::1234") :
       
   179             InetAddress.getByName("1.2.3.4");
       
   180         System.out.format("join %s @ %s only-source %s\n", group.getHostAddress(),
       
   181             nif.getName(), bogus.getHostAddress());
       
   182         try {
       
   183             // may throw UOE
       
   184             key = dc.join(group, nif, bogus);
       
   185 
       
   186             id = sendDatagram(source, nif, group, port);
       
   187             receiveDatagram(dc, null, id);
       
   188 
       
   189             System.out.format("join %s @ %s only-source %s\n", group.getHostAddress(),
       
   190                 nif.getName(), source.getHostAddress());
       
   191             key = dc.join(group, nif, source);
       
   192 
       
   193             id = sendDatagram(source, nif, group, port);
       
   194             receiveDatagram(dc, source, id);
       
   195         } catch (UnsupportedOperationException x) {
       
   196             System.out.println("Include-mode filtering not supported!");
       
   197         }
       
   198 
       
   199         // done
       
   200         dc.close();
       
   201     }
       
   202 
       
   203     public static void main(String[] args) throws IOException {
       
   204         NetworkConfiguration config = NetworkConfiguration.probe();
       
   205 
       
   206         // multicast groups used for the test
       
   207         InetAddress ip4Group = InetAddress.getByName("225.4.5.6");
       
   208         InetAddress ip6Group = InetAddress.getByName("ff02::a");
       
   209 
       
   210         for (NetworkInterface nif: config.ip4Interfaces()) {
       
   211             InetAddress source = config.ip4Addresses(nif).iterator().next();
       
   212             test(nif, ip4Group, source);
       
   213         }
       
   214 
       
   215         for (NetworkInterface nif: config.ip6Interfaces()) {
       
   216             InetAddress source = config.ip6Addresses(nif).iterator().next();
       
   217             test(nif, ip6Group, source);
       
   218         }
       
   219     }
       
   220 }