151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*
27f4b1b8935a58d3f44351083cf5ef19045761de3Yi Kong * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it
651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as
751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation.  Oracle designates this
851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided
951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code.
1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT
1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that
1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code).
1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version
1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation,
1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any
2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions.
2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage java.net;
2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.IOException;
2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.Enumeration;
3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/**
3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The multicast datagram socket class is useful for sending
3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and receiving IP multicast packets.  A MulticastSocket is
3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * a (UDP) DatagramSocket, with additional capabilities for
3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * joining "groups" of other multicast hosts on the internet.
3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <P>
3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * A multicast group is specified by a class D IP address
3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and by a standard UDP port number. Class D IP addresses
3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * are in the range <CODE>224.0.0.0</CODE> to <CODE>239.255.255.255</CODE>,
4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * inclusive. The address 224.0.0.0 is reserved and should not be used.
4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <P>
4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * One would join a multicast group by first creating a MulticastSocket
4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * with the desired port, then invoking the
4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <CODE>joinGroup(InetAddress groupAddr)</CODE>
4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * method:
4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <PRE>
4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * // join a Multicast group and send the group salutations
4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ...
4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * String msg = "Hello";
5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * InetAddress group = InetAddress.getByName("228.5.6.7");
5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * MulticastSocket s = new MulticastSocket(6789);
5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * s.joinGroup(group);
5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DatagramPacket hi = new DatagramPacket(msg.getBytes(), msg.length(),
5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *                             group, 6789);
5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * s.send(hi);
5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * // get their responses!
5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * byte[] buf = new byte[1000];
5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DatagramPacket recv = new DatagramPacket(buf, buf.length);
5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * s.receive(recv);
6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ...
6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * // OK, I'm done talking - leave the group...
6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * s.leaveGroup(group);
6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </PRE>
6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * When one sends a message to a multicast group, <B>all</B> subscribing
6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * recipients to that host and port receive the message (within the
6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * time-to-live range of the packet, see below).  The socket needn't
6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * be a member of the multicast group to send messages to it.
6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <P>
7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * When a socket subscribes to a multicast group/port, it receives
7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * datagrams sent by other hosts to the group/port, as do all other
7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * members of the group and port.  A socket relinquishes membership
7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * in a group by the leaveGroup(InetAddress addr) method.  <B>
7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Multiple MulticastSocket's</B> may subscribe to a multicast group
7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and port concurrently, and they will all receive group datagrams.
7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <P>
7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Currently applets are not allowed to use multicast sockets.
7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author Pavani Diwanji
8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since  JDK1.1
8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic
8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiclass MulticastSocket extends DatagramSocket {
8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Used on some platforms to record if an outgoing interface
8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * has been set for this socket.
8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private boolean interfaceSet;
9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Create a multicast socket.
9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>If there is a security manager,
953a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * its {@code checkListen} method is first called
9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * with 0 as its argument to ensure the operation is allowed.
9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This could result in a SecurityException.
9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * When the socket is created the
10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * {@link DatagramSocket#setReuseAddress(boolean)} method is
10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * called to enable the SO_REUSEADDR socket option.
10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException if an I/O exception occurs
10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * while creating the MulticastSocket
10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  SecurityException  if a security manager exists and its
1063a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     *             {@code checkListen} method doesn't allow the operation.
10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see SecurityManager#checkListen
10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see java.net.DatagramSocket#setReuseAddress(boolean)
10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public MulticastSocket() throws IOException {
11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this(new InetSocketAddress(0));
11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Create a multicast socket and bind it to a specific port.
11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>If there is a security manager,
1183a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * its {@code checkListen} method is first called
1193a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * with the {@code port} argument
12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * as its argument to ensure the operation is allowed.
12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This could result in a SecurityException.
12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * When the socket is created the
12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * {@link DatagramSocket#setReuseAddress(boolean)} method is
12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * called to enable the SO_REUSEADDR socket option.
12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param port port to use
12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException if an I/O exception occurs
12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * while creating the MulticastSocket
13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  SecurityException  if a security manager exists and its
1313a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     *             {@code checkListen} method doesn't allow the operation.
13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see SecurityManager#checkListen
13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see java.net.DatagramSocket#setReuseAddress(boolean)
13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public MulticastSocket(int port) throws IOException {
13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this(new InetSocketAddress(port));
13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Create a MulticastSocket bound to the specified socket address.
14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
1423a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * Or, if the address is {@code null}, create an unbound socket.
1433a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     *
14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>If there is a security manager,
1453a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * its {@code checkListen} method is first called
14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * with the SocketAddress port as its argument to ensure the operation is allowed.
14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This could result in a SecurityException.
14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * When the socket is created the
15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * {@link DatagramSocket#setReuseAddress(boolean)} method is
15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * called to enable the SO_REUSEADDR socket option.
15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
1533a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * @param bindaddr Socket address to bind to, or {@code null} for
15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                 an unbound socket.
15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException if an I/O exception occurs
15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * while creating the MulticastSocket
15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  SecurityException  if a security manager exists and its
1583a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     *             {@code checkListen} method doesn't allow the operation.
15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see SecurityManager#checkListen
16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see java.net.DatagramSocket#setReuseAddress(boolean)
16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.4
16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public MulticastSocket(SocketAddress bindaddr) throws IOException {
16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        super((SocketAddress) null);
16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Enable SO_REUSEADDR before binding
16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        setReuseAddress(true);
16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (bindaddr != null) {
171dbaa8e737b0e5ecff9f7b95b4dbc7e217fc493eeYi Kong            try {
172dbaa8e737b0e5ecff9f7b95b4dbc7e217fc493eeYi Kong                bind(bindaddr);
173dbaa8e737b0e5ecff9f7b95b4dbc7e217fc493eeYi Kong            } finally {
174dbaa8e737b0e5ecff9f7b95b4dbc7e217fc493eeYi Kong                if (!isBound())
175dbaa8e737b0e5ecff9f7b95b4dbc7e217fc493eeYi Kong                    close();
176dbaa8e737b0e5ecff9f7b95b4dbc7e217fc493eeYi Kong            }
17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The lock on the socket's TTL. This is for set/getTTL and
18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * send(packet,ttl).
18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private Object ttlLock = new Object();
18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The lock on the socket's interface - used by setInterface
18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * and getInterface
18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private Object infLock = new Object();
19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The "last" interface set by setInterface on this MulticastSocket
19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private InetAddress infAddress = null;
19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Set the default time-to-live for multicast packets sent out
2003a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * on this {@code MulticastSocket} in order to control the
20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * scope of the multicasts.
20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>The ttl is an <b>unsigned</b> 8-bit quantity, and so <B>must</B> be
2043a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * in the range {@code 0 <= ttl <= 0xFF }.
20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param ttl the time-to-live
20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException if an I/O exception occurs
20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * while setting the default time-to-live value
20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @deprecated use the setTimeToLive method instead, which uses
21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <b>int</b> instead of <b>byte</b> as the type for ttl.
21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #getTTL()
21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    @Deprecated
21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void setTTL(byte ttl) throws IOException {
21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        getImpl().setTTL(ttl);
21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Set the default time-to-live for multicast packets sent out
22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * on this {@code MulticastSocket} in order to control the
22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * scope of the multicasts.
22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <P> The ttl <B>must</B> be in the range {@code  0 <= ttl <=
22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * 255} or an {@code IllegalArgumentException} will be thrown.
22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Multicast packets sent with a TTL of {@code 0} are not transmitted
22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * on the network but may be delivered locally.
22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param  ttl
23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         the time-to-live
23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws  IOException
23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          if an I/O exception occurs while setting the
23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          default time-to-live value
23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #getTimeToLive()
23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void setTimeToLive(int ttl) throws IOException {
24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (ttl < 0 || ttl > 255) {
24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("ttl out of range");
24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        getImpl().setTimeToLive(ttl);
24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Get the default time-to-live for multicast packets sent out on
25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the socket.
25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException if an I/O exception occurs
25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * while getting the default time-to-live value
25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return the default time-to-live value
25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @deprecated use the getTimeToLive method instead, which returns
25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * an <b>int</b> instead of a <b>byte</b>.
25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #setTTL(byte)
25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    @Deprecated
26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public byte getTTL() throws IOException {
26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return getImpl().getTTL();
26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Get the default time-to-live for multicast packets sent out on
26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the socket.
26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException if an I/O exception occurs while
27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * getting the default time-to-live value
27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return the default time-to-live value
27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #setTimeToLive(int)
27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int getTimeToLive() throws IOException {
27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return getImpl().getTimeToLive();
27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Joins a multicast group. Its behavior may be affected by
2823a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code setInterface} or {@code setNetworkInterface}.
28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>If there is a security manager, this method first
2853a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * calls its {@code checkMulticast} method
2863a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * with the {@code mcastaddr} argument
28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * as its argument.
28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param mcastaddr is the multicast address to join
29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException if there is an error joining
29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * or when the address is not a multicast address.
29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  SecurityException  if a security manager exists and its
2943a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code checkMulticast} method doesn't allow the join.
29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see SecurityManager#checkMulticast(InetAddress)
29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void joinGroup(InetAddress mcastaddr) throws IOException {
29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed()) {
30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        checkAddress(mcastaddr, "joinGroup");
30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        SecurityManager security = System.getSecurityManager();
30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (security != null) {
30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            security.checkMulticast(mcastaddr);
30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!mcastaddr.isMulticastAddress()) {
31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Not a multicast address");
31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        /**
31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * required for some platforms where it's not possible to join
31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * a group without setting the interface first.
31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         */
31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        NetworkInterface defaultInterface = NetworkInterface.getDefault();
31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!interfaceSet && defaultInterface != null) {
32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            setNetworkInterface(defaultInterface);
32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        getImpl().join(mcastaddr);
32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Leave a multicast group. Its behavior may be affected by
3283a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code setInterface} or {@code setNetworkInterface}.
32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>If there is a security manager, this method first
3313a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * calls its {@code checkMulticast} method
3323a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * with the {@code mcastaddr} argument
33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * as its argument.
33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param mcastaddr is the multicast address to leave
33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException if there is an error leaving
33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * or when the address is not a multicast address.
33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  SecurityException  if a security manager exists and its
3393a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code checkMulticast} method doesn't allow the operation.
34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see SecurityManager#checkMulticast(InetAddress)
34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void leaveGroup(InetAddress mcastaddr) throws IOException {
34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed()) {
34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        checkAddress(mcastaddr, "leaveGroup");
34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        SecurityManager security = System.getSecurityManager();
35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (security != null) {
35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            security.checkMulticast(mcastaddr);
35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!mcastaddr.isMulticastAddress()) {
35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Not a multicast address");
35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        getImpl().leave(mcastaddr);
35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Joins the specified multicast group at the specified interface.
36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>If there is a security manager, this method first
3653a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * calls its {@code checkMulticast} method
3663a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * with the {@code mcastaddr} argument
36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * as its argument.
36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param mcastaddr is the multicast address to join
37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param netIf specifies the local interface to receive multicast
37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *        datagram packets, or <i>null</i> to defer to the interface set by
37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *       {@link MulticastSocket#setInterface(InetAddress)} or
37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *       {@link MulticastSocket#setNetworkInterface(NetworkInterface)}
37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException if there is an error joining
37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * or when the address is not a multicast address.
37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  SecurityException  if a security manager exists and its
3783a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code checkMulticast} method doesn't allow the join.
37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws  IllegalArgumentException if mcastaddr is null or is a
38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          SocketAddress subclass not supported by this socket
38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see SecurityManager#checkMulticast(InetAddress)
38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.4
38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf)
38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws IOException {
38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress))
39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("Unsupported address type");
39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (oldImpl)
39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new UnsupportedOperationException();
39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        checkAddress(((InetSocketAddress)mcastaddr).getAddress(), "joinGroup");
39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        SecurityManager security = System.getSecurityManager();
39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (security != null) {
39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            security.checkMulticast(((InetSocketAddress)mcastaddr).getAddress());
40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!((InetSocketAddress)mcastaddr).getAddress().isMulticastAddress()) {
40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Not a multicast address");
40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        getImpl().joinGroup(mcastaddr, netIf);
40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Leave a multicast group on a specified local interface.
41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>If there is a security manager, this method first
4133a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * calls its {@code checkMulticast} method
4143a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * with the {@code mcastaddr} argument
41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * as its argument.
41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param mcastaddr is the multicast address to leave
41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param netIf specifies the local interface or <i>null</i> to defer
41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             to the interface set by
42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             {@link MulticastSocket#setInterface(InetAddress)} or
42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             {@link MulticastSocket#setNetworkInterface(NetworkInterface)}
42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException if there is an error leaving
42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * or when the address is not a multicast address.
42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  SecurityException  if a security manager exists and its
4253a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code checkMulticast} method doesn't allow the operation.
42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws  IllegalArgumentException if mcastaddr is null or is a
42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          SocketAddress subclass not supported by this socket
42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see SecurityManager#checkMulticast(InetAddress)
43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.4
43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf)
43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws IOException {
43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress))
43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("Unsupported address type");
43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (oldImpl)
44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new UnsupportedOperationException();
44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        checkAddress(((InetSocketAddress)mcastaddr).getAddress(), "leaveGroup");
44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        SecurityManager security = System.getSecurityManager();
44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (security != null) {
44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            security.checkMulticast(((InetSocketAddress)mcastaddr).getAddress());
44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!((InetSocketAddress)mcastaddr).getAddress().isMulticastAddress()) {
45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Not a multicast address");
45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        getImpl().leaveGroup(mcastaddr, netIf);
45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     }
45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Set the multicast network interface used by methods
45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * whose behavior would be affected by the value of the
45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * network interface. Useful for multihomed hosts.
46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param inf the InetAddress
46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SocketException if there is an error in
46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the underlying protocol, such as a TCP error.
46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #getInterface()
46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void setInterface(InetAddress inf) throws SocketException {
46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed()) {
46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        checkAddress(inf, "setInterface");
47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (infLock) {
47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            getImpl().setOption(SocketOptions.IP_MULTICAST_IF, inf);
47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            infAddress = inf;
47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            interfaceSet = true;
47451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Retrieve the address of the network interface used for
47951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * multicast packets.
48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
4813a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * @return An {@code InetAddress} representing
48251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *  the address of the network interface used for
48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *  multicast packets.
48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SocketException if there is an error in
48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the underlying protocol, such as a TCP error.
48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #setInterface(java.net.InetAddress)
48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public InetAddress getInterface() throws SocketException {
49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed()) {
49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
49351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (infLock) {
49551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            InetAddress ia =
49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                (InetAddress)getImpl().getOption(SocketOptions.IP_MULTICAST_IF);
49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /**
49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * No previous setInterface or interface can be
50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * set using setNetworkInterface
50151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (infAddress == null) {
50351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return ia;
50451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
50551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
50651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /**
50751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Same interface set with setInterface?
50851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
50951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (ia.equals(infAddress)) {
51051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return ia;
51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /**
51451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Different InetAddress from what we set with setInterface
51551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * so enumerate the current interface to see if the
51651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * address set by setInterface is bound to this interface.
51751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
51851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            try {
51951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                NetworkInterface ni = NetworkInterface.getByInetAddress(ia);
5203a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong                Enumeration<InetAddress> addrs = ni.getInetAddresses();
52151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                while (addrs.hasMoreElements()) {
5223a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong                    InetAddress addr = addrs.nextElement();
52351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (addr.equals(infAddress)) {
52451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return infAddress;
52551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
52651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
52751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
52851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /**
52951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * No match so reset infAddress to indicate that the
53051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * interface has changed via means
53151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
53251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                infAddress = null;
53351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return ia;
53451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } catch (Exception e) {
53551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return ia;
53651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
53751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
53851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
53951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
54051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
54151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Specify the network interface for outgoing multicast datagrams
54251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * sent on this socket.
54351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
54451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param netIf the interface
54551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SocketException if there is an error in
54651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the underlying protocol, such as a TCP error.
54751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #getNetworkInterface()
54851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.4
54951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
55051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void setNetworkInterface(NetworkInterface netIf)
55151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws SocketException {
55251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
55351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (infLock) {
55451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            getImpl().setOption(SocketOptions.IP_MULTICAST_IF2, netIf);
55551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            infAddress = null;
55651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            interfaceSet = true;
55751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
55851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
55951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
56051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
56151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Get the multicast network interface set.
56251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
56351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SocketException if there is an error in
56451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the underlying protocol, such as a TCP error.
5653a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * @return the multicast {@code NetworkInterface} currently set
56651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #setNetworkInterface(NetworkInterface)
56751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.4
56851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
56951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public NetworkInterface getNetworkInterface() throws SocketException {
5708bb2df7a21c2e2d0defe26de3f6cbe9657b1cf67Victor Chang        // Android-changed: Support Integer IP_MULTICAST_IF2 values for app compat.
571144bf4e4c08435588381b2ec0df8b9c244eed065Przemyslaw Szczepaniak        Integer niIndex
572144bf4e4c08435588381b2ec0df8b9c244eed065Przemyslaw Szczepaniak            = (Integer)getImpl().getOption(SocketOptions.IP_MULTICAST_IF2);
573144bf4e4c08435588381b2ec0df8b9c244eed065Przemyslaw Szczepaniak        if (niIndex == 0) {
57451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            InetAddress[] addrs = new InetAddress[1];
57551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            addrs[0] = InetAddress.anyLocalAddress();
57651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return new NetworkInterface(addrs[0].getHostName(), 0, addrs);
57751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
578144bf4e4c08435588381b2ec0df8b9c244eed065Przemyslaw Szczepaniak            return NetworkInterface.getByIndex(niIndex);
57951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
58051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
58151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
58251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
58351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Disable/Enable local loopback of multicast datagrams
58451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The option is used by the platform's networking code as a hint
58551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * for setting whether multicast data will be looped back to
58651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the local socket.
58751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
58851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>Because this option is a hint, applications that want to
58951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * verify what loopback mode is set to should call
59051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * {@link #getLoopbackMode()}
5913a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * @param disable {@code true} to disable the LoopbackMode
59251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws SocketException if an error occurs while setting the value
59351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.4
59451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #getLoopbackMode
59551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
59651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void setLoopbackMode(boolean disable) throws SocketException {
59751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        getImpl().setOption(SocketOptions.IP_MULTICAST_LOOP, Boolean.valueOf(disable));
59851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
59951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
60051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
60151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Get the setting for local loopback of multicast datagrams.
60251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
60351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws SocketException  if an error occurs while getting the value
60451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return true if the LoopbackMode has been disabled
60551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.4
60651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #setLoopbackMode
60751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
60851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean getLoopbackMode() throws SocketException {
60951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return ((Boolean)getImpl().getOption(SocketOptions.IP_MULTICAST_LOOP)).booleanValue();
61051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
61151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
61251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
61351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Sends a datagram packet to the destination, with a TTL (time-
61451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * to-live) other than the default for the socket.  This method
61551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * need only be used in instances where a particular TTL is desired;
61651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * otherwise it is preferable to set a TTL once on the socket, and
61751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * use that default TTL for all packets.  This method does <B>not
61851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * </B> alter the default TTL for the socket. Its behavior may be
6193a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * affected by {@code setInterface}.
62051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
62151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>If there is a security manager, this method first performs some
6223a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * security checks. First, if {@code p.getAddress().isMulticastAddress()}
62351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * is true, this method calls the
6243a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * security manager's {@code checkMulticast} method
6253a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * with {@code p.getAddress()} and {@code ttl} as its arguments.
62651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If the evaluation of that expression is false,
62751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * this method instead calls the security manager's
6283a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code checkConnect} method with arguments
6293a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code p.getAddress().getHostAddress()} and
6303a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code p.getPort()}. Each call to a security manager method
63151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * could result in a SecurityException if the operation is not allowed.
63251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
63351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param p is the packet to be sent. The packet should contain
63451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the destination multicast ip address and the data to be sent.
63551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * One does not need to be the member of the group to send
63651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * packets to a destination multicast address.
63751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param ttl optional time to live for multicast packet.
63851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * default ttl is 1.
63951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
64051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException is raised if an error occurs i.e
64151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * error while setting ttl.
64251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  SecurityException  if a security manager exists and its
6433a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     *             {@code checkMulticast} or {@code checkConnect}
64451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             method doesn't allow the send.
64551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
64651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @deprecated Use the following code or its equivalent instead:
64751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *  ......
64851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *  int ttl = mcastSocket.getTimeToLive();
64951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *  mcastSocket.setTimeToLive(newttl);
65051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *  mcastSocket.send(p);
65151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *  mcastSocket.setTimeToLive(ttl);
65251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *  ......
65351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
65451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see DatagramSocket#send
65551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see DatagramSocket#receive
65651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see SecurityManager#checkMulticast(java.net.InetAddress, byte)
65751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see SecurityManager#checkConnect
65851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
65951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    @Deprecated
66051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void send(DatagramPacket p, byte ttl)
66151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws IOException {
66251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (isClosed())
66351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new SocketException("Socket is closed");
66451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            checkAddress(p.getAddress(), "send");
66551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            synchronized(ttlLock) {
66651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                synchronized(p) {
66751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (connectState == ST_NOT_CONNECTED) {
66851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // Security manager makes sure that the multicast address
66951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // is allowed one and that the ttl used is less
67051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // than the allowed maxttl.
67151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        SecurityManager security = System.getSecurityManager();
67251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if (security != null) {
67351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            if (p.getAddress().isMulticastAddress()) {
67451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                security.checkMulticast(p.getAddress(), ttl);
67551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            } else {
67651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                security.checkConnect(p.getAddress().getHostAddress(),
67751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                                      p.getPort());
67851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            }
67951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
68051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } else {
68151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // we're connected
68251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        InetAddress packetAddress = null;
68351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        packetAddress = p.getAddress();
68451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if (packetAddress == null) {
68551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            p.setAddress(connectedAddress);
68651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            p.setPort(connectedPort);
68751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        } else if ((!packetAddress.equals(connectedAddress)) ||
68851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                   p.getPort() != connectedPort) {
68951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            throw new SecurityException("connected address and packet address" +
69051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                                        " differ");
69151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
69251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
69351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    byte dttl = getTTL();
69451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    try {
69551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if (ttl != dttl) {
69651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            // set the ttl
69751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            getImpl().setTTL(ttl);
69851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
69951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // call the datagram method to send
70051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        getImpl().send(p);
70151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } finally {
70251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // set it back to default
70351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if (ttl != dttl) {
70451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            getImpl().setTTL(dttl);
70551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
70651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
70751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } // synch p
70851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }  //synch ttl
70951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    } //method
71051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
711