MulticastSocket.java revision dbaa8e737b0e5ecff9f7b95b4dbc7e217fc493ee
151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*
251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 1995, 2007, 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.io.InterruptedIOException;
3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.Enumeration;
3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/**
3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The multicast datagram socket class is useful for sending
3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and receiving IP multicast packets.  A MulticastSocket is
3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * a (UDP) DatagramSocket, with additional capabilities for
3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * joining "groups" of other multicast hosts on the internet.
3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <P>
3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * A multicast group is specified by a class D IP address
3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and by a standard UDP port number. Class D IP addresses
4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * are in the range <CODE>224.0.0.0</CODE> to <CODE>239.255.255.255</CODE>,
4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * inclusive. The address 224.0.0.0 is reserved and should not be used.
4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <P>
4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * One would join a multicast group by first creating a MulticastSocket
4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * with the desired port, then invoking the
4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <CODE>joinGroup(InetAddress groupAddr)</CODE>
4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * method:
4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <PRE>
4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * // join a Multicast group and send the group salutations
4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ...
5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * String msg = "Hello";
5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * InetAddress group = InetAddress.getByName("228.5.6.7");
5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * MulticastSocket s = new MulticastSocket(6789);
5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * s.joinGroup(group);
5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DatagramPacket hi = new DatagramPacket(msg.getBytes(), msg.length(),
5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *                             group, 6789);
5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * s.send(hi);
5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * // get their responses!
5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * byte[] buf = new byte[1000];
5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DatagramPacket recv = new DatagramPacket(buf, buf.length);
6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * s.receive(recv);
6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ...
6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * // OK, I'm done talking - leave the group...
6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * s.leaveGroup(group);
6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </PRE>
6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * When one sends a message to a multicast group, <B>all</B> subscribing
6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * recipients to that host and port receive the message (within the
6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * time-to-live range of the packet, see below).  The socket needn't
6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * be a member of the multicast group to send messages to it.
7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <P>
7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * When a socket subscribes to a multicast group/port, it receives
7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * datagrams sent by other hosts to the group/port, as do all other
7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * members of the group and port.  A socket relinquishes membership
7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * in a group by the leaveGroup(InetAddress addr) method.  <B>
7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Multiple MulticastSocket's</B> may subscribe to a multicast group
7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and port concurrently, and they will all receive group datagrams.
7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <P>
7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Currently applets are not allowed to use multicast sockets.
7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author Pavani Diwanji
8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since  JDK1.1
8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic
8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiclass MulticastSocket extends DatagramSocket {
8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Used on some platforms to record if an outgoing interface
8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * has been set for this socket.
8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private boolean interfaceSet;
9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Create a multicast socket.
9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>If there is a security manager,
963a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * its {@code checkListen} method is first called
9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * with 0 as its argument to ensure the operation is allowed.
9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This could result in a SecurityException.
9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * When the socket is created the
10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * {@link DatagramSocket#setReuseAddress(boolean)} method is
10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * called to enable the SO_REUSEADDR socket option.
10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException if an I/O exception occurs
10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * while creating the MulticastSocket
10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  SecurityException  if a security manager exists and its
1073a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     *             {@code checkListen} method doesn't allow the operation.
10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see SecurityManager#checkListen
10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see java.net.DatagramSocket#setReuseAddress(boolean)
11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public MulticastSocket() throws IOException {
11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this(new InetSocketAddress(0));
11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Create a multicast socket and bind it to a specific port.
11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>If there is a security manager,
1193a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * its {@code checkListen} method is first called
1203a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * with the {@code port} argument
12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * as its argument to ensure the operation is allowed.
12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This could result in a SecurityException.
12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * When the socket is created the
12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * {@link DatagramSocket#setReuseAddress(boolean)} method is
12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * called to enable the SO_REUSEADDR socket option.
12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param port port to use
12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException if an I/O exception occurs
13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * while creating the MulticastSocket
13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  SecurityException  if a security manager exists and its
1323a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     *             {@code checkListen} method doesn't allow the operation.
13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see SecurityManager#checkListen
13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see java.net.DatagramSocket#setReuseAddress(boolean)
13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public MulticastSocket(int port) throws IOException {
13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this(new InetSocketAddress(port));
13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Create a MulticastSocket bound to the specified socket address.
14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
1433a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * Or, if the address is {@code null}, create an unbound socket.
1443a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     *
14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>If there is a security manager,
1463a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * its {@code checkListen} method is first called
14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * with the SocketAddress port as its argument to ensure the operation is allowed.
14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This could result in a SecurityException.
14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * When the socket is created the
15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * {@link DatagramSocket#setReuseAddress(boolean)} method is
15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * called to enable the SO_REUSEADDR socket option.
15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
1543a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * @param bindaddr Socket address to bind to, or {@code null} for
15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                 an unbound socket.
15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException if an I/O exception occurs
15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * while creating the MulticastSocket
15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  SecurityException  if a security manager exists and its
1593a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     *             {@code checkListen} method doesn't allow the operation.
16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see SecurityManager#checkListen
16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see java.net.DatagramSocket#setReuseAddress(boolean)
16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.4
16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public MulticastSocket(SocketAddress bindaddr) throws IOException {
16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        super((SocketAddress) null);
16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Enable SO_REUSEADDR before binding
16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        setReuseAddress(true);
17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (bindaddr != null) {
172dbaa8e737b0e5ecff9f7b95b4dbc7e217fc493eeYi Kong            try {
173dbaa8e737b0e5ecff9f7b95b4dbc7e217fc493eeYi Kong                bind(bindaddr);
174dbaa8e737b0e5ecff9f7b95b4dbc7e217fc493eeYi Kong            } finally {
175dbaa8e737b0e5ecff9f7b95b4dbc7e217fc493eeYi Kong                if (!isBound())
176dbaa8e737b0e5ecff9f7b95b4dbc7e217fc493eeYi Kong                    close();
177dbaa8e737b0e5ecff9f7b95b4dbc7e217fc493eeYi Kong            }
17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The lock on the socket's TTL. This is for set/getTTL and
18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * send(packet,ttl).
18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private Object ttlLock = new Object();
18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The lock on the socket's interface - used by setInterface
18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * and getInterface
19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private Object infLock = new Object();
19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The "last" interface set by setInterface on this MulticastSocket
19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private InetAddress infAddress = null;
19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Set the default time-to-live for multicast packets sent out
2013a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * on this {@code MulticastSocket} in order to control the
20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * scope of the multicasts.
20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>The ttl is an <b>unsigned</b> 8-bit quantity, and so <B>must</B> be
2053a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * in the range {@code 0 <= ttl <= 0xFF }.
20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param ttl the time-to-live
20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException if an I/O exception occurs
20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * while setting the default time-to-live value
21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @deprecated use the setTimeToLive method instead, which uses
21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <b>int</b> instead of <b>byte</b> as the type for ttl.
21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #getTTL()
21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    @Deprecated
21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void setTTL(byte ttl) throws IOException {
21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        getImpl().setTTL(ttl);
21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Set the default time-to-live for multicast packets sent out
22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * on this {@code MulticastSocket} in order to control the
22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * scope of the multicasts.
22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <P> The ttl <B>must</B> be in the range {@code  0 <= ttl <=
22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * 255} or an {@code IllegalArgumentException} will be thrown.
22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Multicast packets sent with a TTL of {@code 0} are not transmitted
22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * on the network but may be delivered locally.
23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param  ttl
23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *         the time-to-live
23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws  IOException
23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          if an I/O exception occurs while setting the
23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          default time-to-live value
23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #getTimeToLive()
23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void setTimeToLive(int ttl) throws IOException {
24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (ttl < 0 || ttl > 255) {
24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("ttl out of range");
24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        getImpl().setTimeToLive(ttl);
24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Get the default time-to-live for multicast packets sent out on
25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the socket.
25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException if an I/O exception occurs
25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * while getting the default time-to-live value
25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return the default time-to-live value
25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @deprecated use the getTimeToLive method instead, which returns
25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * an <b>int</b> instead of a <b>byte</b>.
25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #setTTL(byte)
25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    @Deprecated
26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public byte getTTL() throws IOException {
26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return getImpl().getTTL();
26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Get the default time-to-live for multicast packets sent out on
26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the socket.
27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException if an I/O exception occurs while
27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * getting the default time-to-live value
27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return the default time-to-live value
27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #setTimeToLive(int)
27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int getTimeToLive() throws IOException {
27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return getImpl().getTimeToLive();
27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Joins a multicast group. Its behavior may be affected by
2833a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code setInterface} or {@code setNetworkInterface}.
28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>If there is a security manager, this method first
2863a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * calls its {@code checkMulticast} method
2873a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * with the {@code mcastaddr} argument
28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * as its argument.
28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param mcastaddr is the multicast address to join
29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException if there is an error joining
29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * or when the address is not a multicast address.
29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  SecurityException  if a security manager exists and its
2953a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code checkMulticast} method doesn't allow the join.
29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see SecurityManager#checkMulticast(InetAddress)
29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void joinGroup(InetAddress mcastaddr) throws IOException {
30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed()) {
30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        checkAddress(mcastaddr, "joinGroup");
30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        SecurityManager security = System.getSecurityManager();
30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (security != null) {
30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            security.checkMulticast(mcastaddr);
30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!mcastaddr.isMulticastAddress()) {
31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Not a multicast address");
31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        /**
31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * required for some platforms where it's not possible to join
31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * a group without setting the interface first.
31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         */
31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        NetworkInterface defaultInterface = NetworkInterface.getDefault();
31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!interfaceSet && defaultInterface != null) {
32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            setNetworkInterface(defaultInterface);
32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        getImpl().join(mcastaddr);
32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Leave a multicast group. Its behavior may be affected by
3293a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code setInterface} or {@code setNetworkInterface}.
33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>If there is a security manager, this method first
3323a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * calls its {@code checkMulticast} method
3333a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * with the {@code mcastaddr} argument
33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * as its argument.
33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param mcastaddr is the multicast address to leave
33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException if there is an error leaving
33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * or when the address is not a multicast address.
33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  SecurityException  if a security manager exists and its
3403a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code checkMulticast} method doesn't allow the operation.
34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see SecurityManager#checkMulticast(InetAddress)
34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void leaveGroup(InetAddress mcastaddr) throws IOException {
34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed()) {
34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        checkAddress(mcastaddr, "leaveGroup");
35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        SecurityManager security = System.getSecurityManager();
35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (security != null) {
35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            security.checkMulticast(mcastaddr);
35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!mcastaddr.isMulticastAddress()) {
35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Not a multicast address");
35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        getImpl().leave(mcastaddr);
36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Joins the specified multicast group at the specified interface.
36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>If there is a security manager, this method first
3663a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * calls its {@code checkMulticast} method
3673a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * with the {@code mcastaddr} argument
36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * as its argument.
36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param mcastaddr is the multicast address to join
37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param netIf specifies the local interface to receive multicast
37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *        datagram packets, or <i>null</i> to defer to the interface set by
37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *       {@link MulticastSocket#setInterface(InetAddress)} or
37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *       {@link MulticastSocket#setNetworkInterface(NetworkInterface)}
37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException if there is an error joining
37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * or when the address is not a multicast address.
37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  SecurityException  if a security manager exists and its
3793a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code checkMulticast} method doesn't allow the join.
38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws  IllegalArgumentException if mcastaddr is null or is a
38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          SocketAddress subclass not supported by this socket
38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see SecurityManager#checkMulticast(InetAddress)
38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.4
38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf)
38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws IOException {
38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress))
39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("Unsupported address type");
39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (oldImpl)
39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new UnsupportedOperationException();
39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        checkAddress(((InetSocketAddress)mcastaddr).getAddress(), "joinGroup");
39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        SecurityManager security = System.getSecurityManager();
39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (security != null) {
40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            security.checkMulticast(((InetSocketAddress)mcastaddr).getAddress());
40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!((InetSocketAddress)mcastaddr).getAddress().isMulticastAddress()) {
40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Not a multicast address");
40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        getImpl().joinGroup(mcastaddr, netIf);
40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Leave a multicast group on a specified local interface.
41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>If there is a security manager, this method first
4143a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * calls its {@code checkMulticast} method
4153a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * with the {@code mcastaddr} argument
41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * as its argument.
41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param mcastaddr is the multicast address to leave
41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param netIf specifies the local interface or <i>null</i> to defer
42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             to the interface set by
42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             {@link MulticastSocket#setInterface(InetAddress)} or
42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             {@link MulticastSocket#setNetworkInterface(NetworkInterface)}
42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception IOException if there is an error leaving
42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * or when the address is not a multicast address.
42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  SecurityException  if a security manager exists and its
4263a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * {@code checkMulticast} method doesn't allow the operation.
42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @throws  IllegalArgumentException if mcastaddr is null or is a
42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          SocketAddress subclass not supported by this socket
42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see SecurityManager#checkMulticast(InetAddress)
43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.4
43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf)
43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws IOException {
43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed())
43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress))
43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new IllegalArgumentException("Unsupported address type");
44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (oldImpl)
44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new UnsupportedOperationException();
44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        checkAddress(((InetSocketAddress)mcastaddr).getAddress(), "leaveGroup");
44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        SecurityManager security = System.getSecurityManager();
44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (security != null) {
44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            security.checkMulticast(((InetSocketAddress)mcastaddr).getAddress());
44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!((InetSocketAddress)mcastaddr).getAddress().isMulticastAddress()) {
45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Not a multicast address");
45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        getImpl().leaveGroup(mcastaddr, netIf);
45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     }
45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Set the multicast network interface used by methods
45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * whose behavior would be affected by the value of the
46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * network interface. Useful for multihomed hosts.
46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param inf the InetAddress
46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SocketException if there is an error in
46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the underlying protocol, such as a TCP error.
46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #getInterface()
46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void setInterface(InetAddress inf) throws SocketException {
46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed()) {
46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        checkAddress(inf, "setInterface");
47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (infLock) {
47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            getImpl().setOption(SocketOptions.IP_MULTICAST_IF, inf);
47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            infAddress = inf;
47451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            interfaceSet = true;
47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
47951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Retrieve the address of the network interface used for
48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * multicast packets.
48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
4823a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * @return An {@code InetAddress} representing
48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *  the address of the network interface used for
48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *  multicast packets.
48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SocketException if there is an error in
48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the underlying protocol, such as a TCP error.
48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #setInterface(java.net.InetAddress)
49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public InetAddress getInterface() throws SocketException {
49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isClosed()) {
49351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new SocketException("Socket is closed");
49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
49551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (infLock) {
49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            InetAddress ia =
49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                (InetAddress)getImpl().getOption(SocketOptions.IP_MULTICAST_IF);
49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /**
50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * No previous setInterface or interface can be
50151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * set using setNetworkInterface
50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
50351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (infAddress == null) {
50451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return ia;
50551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
50651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
50751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /**
50851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Same interface set with setInterface?
50951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
51051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (ia.equals(infAddress)) {
51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return ia;
51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
51451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            /**
51551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * Different InetAddress from what we set with setInterface
51651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * so enumerate the current interface to see if the
51751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             * address set by setInterface is bound to this interface.
51851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski             */
51951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            try {
52051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                NetworkInterface ni = NetworkInterface.getByInetAddress(ia);
5213a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong                Enumeration<InetAddress> addrs = ni.getInetAddresses();
52251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                while (addrs.hasMoreElements()) {
5233a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong                    InetAddress addr = addrs.nextElement();
52451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (addr.equals(infAddress)) {
52551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return infAddress;
52651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
52751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
52851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
52951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                /**
53051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * No match so reset infAddress to indicate that the
53151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 * interface has changed via means
53251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                 */
53351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                infAddress = null;
53451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return ia;
53551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } catch (Exception e) {
53651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return ia;
53751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
53851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
53951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
54051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
54151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
54251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Specify the network interface for outgoing multicast datagrams
54351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * sent on this socket.
54451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
54551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param netIf the interface
54651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SocketException if there is an error in
54751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the underlying protocol, such as a TCP error.
54851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #getNetworkInterface()
54951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.4
55051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
55151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void setNetworkInterface(NetworkInterface netIf)
55251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        throws SocketException {
55351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
55451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized (infLock) {
55551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            getImpl().setOption(SocketOptions.IP_MULTICAST_IF2, netIf);
55651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            infAddress = null;
55751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            interfaceSet = true;
55851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
55951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
56051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
56151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
56251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Get the multicast network interface set.
56351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
56451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SocketException if there is an error in
56551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the underlying protocol, such as a TCP error.
5663a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong     * @return the multicast {@code NetworkInterface} currently set
56751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see #setNetworkInterface(NetworkInterface)
56851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since 1.4
56951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
57051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public NetworkInterface getNetworkInterface() throws SocketException {
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