/** Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.*********************/package java.net;import java.io.IOException;import java.util.Collections;import java.util.Enumeration;import java.util.Set;/*** The multicast datagram socket class is useful for sending* and receiving IP multicast packets. A MulticastSocket is* a (UDP) DatagramSocket, with additional capabilities for* joining "groups" of other multicast hosts on the internet.* <P>* A multicast group is specified by a class D IP address* and by a standard UDP port number. Class D IP addresses* are in the range <CODE>224.0.0.0</CODE> to <CODE>239.255.255.255</CODE>,* inclusive. The address 224.0.0.0 is reserved and should not be used.* <P>* One would join a multicast group by first creating a MulticastSocket* with the desired port, then invoking the* <CODE>joinGroup(InetAddress groupAddr)</CODE>* method:* <PRE>* // join a Multicast group and send the group salutations* ...* String msg = "Hello";* InetAddress group = InetAddress.getByName("228.5.6.7");* MulticastSocket s = new MulticastSocket(6789);* s.joinGroup(group);* DatagramPacket hi = new DatagramPacket(msg.getBytes(), msg.length(),* group, 6789);* s.send(hi);* // get their responses!* byte[] buf = new byte[1000];* DatagramPacket recv = new DatagramPacket(buf, buf.length);* s.receive(recv);* ...* // OK, I'm done talking - leave the group...* s.leaveGroup(group);* </PRE>** When one sends a message to a multicast group, <B>all</B> subscribing* recipients to that host and port receive the message (within the* time-to-live range of the packet, see below). The socket needn't* be a member of the multicast group to send messages to it.* <P>* When a socket subscribes to a multicast group/port, it receives* datagrams sent by other hosts to the group/port, as do all other* members of the group and port. A socket relinquishes membership* in a group by the leaveGroup(InetAddress addr) method. <B>* Multiple MulticastSocket's</B> may subscribe to a multicast group* and port concurrently, and they will all receive group datagrams.* <P>* Currently applets are not allowed to use multicast sockets.** @author Pavani Diwanji* @since 1.1*/publicclass MulticastSocket extends DatagramSocket {/*** Used on some platforms to record if an outgoing interface* has been set for this socket.*/private boolean interfaceSet;/*** Create a multicast socket.** <p>* If there is a security manager, its {@code checkListen} method is first* called with 0 as its argument to ensure the operation is allowed. This* could result in a SecurityException.* <p>* When the socket is created the* {@link DatagramSocket#setReuseAddress(boolean)} method is called to* enable the SO_REUSEADDR socket option.** @exception IOException if an I/O exception occurs while creating the* MulticastSocket* @exception SecurityException if a security manager exists and its* {@code checkListen} method doesn't allow the operation.* @see SecurityManager#checkListen* @see java.net.DatagramSocket#setReuseAddress(boolean)* @see java.net.DatagramSocketImpl#setOption(SocketOption, Object)*/public MulticastSocket() throws IOException {this(new InetSocketAddress(0));}/*** Create a multicast socket and bind it to a specific port.** <p>If there is a security manager,* its {@code checkListen} method is first called* with the {@code port} argument* as its argument to ensure the operation is allowed.* This could result in a SecurityException.* <p>* When the socket is created the* {@link DatagramSocket#setReuseAddress(boolean)} method is* called to enable the SO_REUSEADDR socket option.** @param port port to use* @exception IOException if an I/O exception occurs* while creating the MulticastSocket* @exception SecurityException if a security manager exists and its* {@code checkListen} method doesn't allow the operation.* @see SecurityManager#checkListen* @see java.net.DatagramSocket#setReuseAddress(boolean)*/public MulticastSocket(int port) throws IOException {this(new InetSocketAddress(port));}/*** Create a MulticastSocket bound to the specified socket address.* <p>* Or, if the address is {@code null}, create an unbound socket.** <p>If there is a security manager,* its {@code checkListen} method is first called* with the SocketAddress port as its argument to ensure the operation is allowed.* This could result in a SecurityException.* <p>* When the socket is created the* {@link DatagramSocket#setReuseAddress(boolean)} method is* called to enable the SO_REUSEADDR socket option.** @param bindaddr Socket address to bind to, or {@code null} for* an unbound socket.* @exception IOException if an I/O exception occurs* while creating the MulticastSocket* @exception SecurityException if a security manager exists and its* {@code checkListen} method doesn't allow the operation.* @see SecurityManager#checkListen* @see java.net.DatagramSocket#setReuseAddress(boolean)** @since 1.4*/public MulticastSocket(SocketAddress bindaddr) throws IOException {super((SocketAddress) null);// Enable SO_REUSEADDR before bindingsetReuseAddress(true);if (bindaddr != null) {try {bind(bindaddr);} finally {if (!isBound()) {close();}}}}/*** The lock on the socket's TTL. This is for set/getTTL and* send(packet,ttl).*/private Object ttlLock = new Object();/*** The lock on the socket's interface - used by setInterface* and getInterface*/private Object infLock = new Object();/*** The "last" interface set by setInterface on this MulticastSocket*/private InetAddress infAddress = null;/*** Set the default time-to-live for multicast packets sent out* on this {@code MulticastSocket} in order to control the* scope of the multicasts.** <p>The ttl is an <b>unsigned</b> 8-bit quantity, and so <B>must</B> be* in the range {@code 0 <= ttl <= 0xFF }.** @param ttl the time-to-live* @exception IOException if an I/O exception occurs* while setting the default time-to-live value* @deprecated use the setTimeToLive method instead, which uses* <b>int</b> instead of <b>byte</b> as the type for ttl.* @see #getTTL()*/@Deprecatedpublic void setTTL(byte ttl) throws IOException {if (isClosed())throw new SocketException("Socket is closed");getImpl().setTTL(ttl);}/*** Set the default time-to-live for multicast packets sent out* on this {@code MulticastSocket} in order to control the* scope of the multicasts.** <P> The ttl <B>must</B> be in the range {@code 0 <= ttl <=* 255} or an {@code IllegalArgumentException} will be thrown.* Multicast packets sent with a TTL of {@code 0} are not transmitted* on the network but may be delivered locally.** @param ttl* the time-to-live** @throws IOException* if an I/O exception occurs while setting the* default time-to-live value** @see #getTimeToLive()*/public void setTimeToLive(int ttl) throws IOException {if (ttl < 0 || ttl > 255) {throw new IllegalArgumentException("ttl out of range");}if (isClosed())throw new SocketException("Socket is closed");getImpl().setTimeToLive(ttl);}/*** Get the default time-to-live for multicast packets sent out on* the socket.** @exception IOException if an I/O exception occurs* while getting the default time-to-live value* @return the default time-to-live value* @deprecated use the getTimeToLive method instead, which returns* an <b>int</b> instead of a <b>byte</b>.* @see #setTTL(byte)*/@Deprecatedpublic byte getTTL() throws IOException {if (isClosed())throw new SocketException("Socket is closed");return getImpl().getTTL();}/*** Get the default time-to-live for multicast packets sent out on* the socket.* @exception IOException if an I/O exception occurs while* getting the default time-to-live value* @return the default time-to-live value* @see #setTimeToLive(int)*/public int getTimeToLive() throws IOException {if (isClosed())throw new SocketException("Socket is closed");return getImpl().getTimeToLive();}/*** Joins a multicast group. Its behavior may be affected by* {@code setInterface} or {@code setNetworkInterface}.** <p>If there is a security manager, this method first* calls its {@code checkMulticast} method* with the {@code mcastaddr} argument* as its argument.** @param mcastaddr is the multicast address to join** @exception IOException if there is an error joining, or when the address* is not a multicast address, or the platform does not support* multicasting* @exception SecurityException if a security manager exists and its* {@code checkMulticast} method doesn't allow the join.** @see SecurityManager#checkMulticast(InetAddress)*/public void joinGroup(InetAddress mcastaddr) throws IOException {if (isClosed()) {throw new SocketException("Socket is closed");}checkAddress(mcastaddr, "joinGroup");SecurityManager security = System.getSecurityManager();if (security != null) {security.checkMulticast(mcastaddr);}if (!mcastaddr.isMulticastAddress()) {throw new SocketException("Not a multicast address");}/*** required for some platforms where it's not possible to join* a group without setting the interface first.*/NetworkInterface defaultInterface = NetworkInterface.getDefault();if (!interfaceSet && defaultInterface != null) {setNetworkInterface(defaultInterface);}getImpl().join(mcastaddr);}/*** Leave a multicast group. Its behavior may be affected by* {@code setInterface} or {@code setNetworkInterface}.** <p>If there is a security manager, this method first* calls its {@code checkMulticast} method* with the {@code mcastaddr} argument* as its argument.** @param mcastaddr is the multicast address to leave* @exception IOException if there is an error leaving* or when the address is not a multicast address.* @exception SecurityException if a security manager exists and its* {@code checkMulticast} method doesn't allow the operation.** @see SecurityManager#checkMulticast(InetAddress)*/public void leaveGroup(InetAddress mcastaddr) throws IOException {if (isClosed()) {throw new SocketException("Socket is closed");}checkAddress(mcastaddr, "leaveGroup");SecurityManager security = System.getSecurityManager();if (security != null) {security.checkMulticast(mcastaddr);}if (!mcastaddr.isMulticastAddress()) {throw new SocketException("Not a multicast address");}getImpl().leave(mcastaddr);}/*** Joins the specified multicast group at the specified interface.** <p>If there is a security manager, this method first* calls its {@code checkMulticast} method* with the {@code mcastaddr} argument* as its argument.** @param mcastaddr is the multicast address to join* @param netIf specifies the local interface to receive multicast* datagram packets, or <i>null</i> to defer to the interface set by* {@link MulticastSocket#setInterface(InetAddress)} or* {@link MulticastSocket#setNetworkInterface(NetworkInterface)}** @exception IOException if there is an error joining, or when the address* is not a multicast address, or the platform does not support* multicasting* @exception SecurityException if a security manager exists and its* {@code checkMulticast} method doesn't allow the join.* @throws IllegalArgumentException if mcastaddr is null or is a* SocketAddress subclass not supported by this socket** @see SecurityManager#checkMulticast(InetAddress)* @since 1.4*/public void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf)throws IOException {if (isClosed())throw new SocketException("Socket is closed");if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress))throw new IllegalArgumentException("Unsupported address type");if (oldImpl)throw new UnsupportedOperationException();checkAddress(((InetSocketAddress)mcastaddr).getAddress(), "joinGroup");SecurityManager security = System.getSecurityManager();if (security != null) {security.checkMulticast(((InetSocketAddress)mcastaddr).getAddress());}if (!((InetSocketAddress)mcastaddr).getAddress().isMulticastAddress()) {throw new SocketException("Not a multicast address");}getImpl().joinGroup(mcastaddr, netIf);}/*** Leave a multicast group on a specified local interface.** <p>If there is a security manager, this method first* calls its {@code checkMulticast} method* with the {@code mcastaddr} argument* as its argument.** @param mcastaddr is the multicast address to leave* @param netIf specifies the local interface or <i>null</i> to defer* to the interface set by* {@link MulticastSocket#setInterface(InetAddress)} or* {@link MulticastSocket#setNetworkInterface(NetworkInterface)}* @exception IOException if there is an error leaving* or when the address is not a multicast address.* @exception SecurityException if a security manager exists and its* {@code checkMulticast} method doesn't allow the operation.* @throws IllegalArgumentException if mcastaddr is null or is a* SocketAddress subclass not supported by this socket** @see SecurityManager#checkMulticast(InetAddress)* @since 1.4*/public void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf)throws IOException {if (isClosed())throw new SocketException("Socket is closed");if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress))throw new IllegalArgumentException("Unsupported address type");if (oldImpl)throw new UnsupportedOperationException();checkAddress(((InetSocketAddress)mcastaddr).getAddress(), "leaveGroup");SecurityManager security = System.getSecurityManager();if (security != null) {security.checkMulticast(((InetSocketAddress)mcastaddr).getAddress());}if (!((InetSocketAddress)mcastaddr).getAddress().isMulticastAddress()) {throw new SocketException("Not a multicast address");}getImpl().leaveGroup(mcastaddr, netIf);}/*** Set the multicast network interface used by methods* whose behavior would be affected by the value of the* network interface. Useful for multihomed hosts.* @param inf the InetAddress* @exception SocketException if there is an error in* the underlying protocol, such as a TCP error.* @see #getInterface()*/public void setInterface(InetAddress inf) throws SocketException {if (isClosed()) {throw new SocketException("Socket is closed");}checkAddress(inf, "setInterface");synchronized (infLock) {getImpl().setOption(SocketOptions.IP_MULTICAST_IF, inf);infAddress = inf;interfaceSet = true;}}/*** Retrieve the address of the network interface used for* multicast packets.** @return An {@code InetAddress} representing* the address of the network interface used for* multicast packets.** @exception SocketException if there is an error in* the underlying protocol, such as a TCP error.** @see #setInterface(java.net.InetAddress)*/public InetAddress getInterface() throws SocketException {if (isClosed()) {throw new SocketException("Socket is closed");}synchronized (infLock) {InetAddress ia =(InetAddress)getImpl().getOption(SocketOptions.IP_MULTICAST_IF);/*** No previous setInterface or interface can be* set using setNetworkInterface*/if (infAddress == null) {return ia;}/*** Same interface set with setInterface?*/if (ia.equals(infAddress)) {return ia;}/*** Different InetAddress from what we set with setInterface* so enumerate the current interface to see if the* address set by setInterface is bound to this interface.*/try {NetworkInterface ni = NetworkInterface.getByInetAddress(ia);Enumeration<InetAddress> addrs = ni.getInetAddresses();while (addrs.hasMoreElements()) {InetAddress addr = addrs.nextElement();if (addr.equals(infAddress)) {return infAddress;}}/*** No match so reset infAddress to indicate that the* interface has changed via means*/infAddress = null;return ia;} catch (Exception e) {return ia;}}}/*** Specify the network interface for outgoing multicast datagrams* sent on this socket.** @param netIf the interface* @exception SocketException if there is an error in* the underlying protocol, such as a TCP error.* @see #getNetworkInterface()* @since 1.4*/public void setNetworkInterface(NetworkInterface netIf)throws SocketException {synchronized (infLock) {getImpl().setOption(SocketOptions.IP_MULTICAST_IF2, netIf);infAddress = null;interfaceSet = true;}}/*** Get the multicast network interface set.** @exception SocketException if there is an error in* the underlying protocol, such as a TCP error.* @return the multicast {@code NetworkInterface} currently set* @see #setNetworkInterface(NetworkInterface)* @since 1.4*/public NetworkInterface getNetworkInterface() throws SocketException {NetworkInterface ni= (NetworkInterface)getImpl().getOption(SocketOptions.IP_MULTICAST_IF2);if ((ni.getIndex() == 0) || (ni.getIndex() == -1)) {InetAddress[] addrs = new InetAddress[1];addrs[0] = InetAddress.anyLocalAddress();return new NetworkInterface(addrs[0].getHostName(), 0, addrs);} else {return ni;}}/*** Disable/Enable local loopback of multicast datagrams* The option is used by the platform's networking code as a hint* for setting whether multicast data will be looped back to* the local socket.** <p>Because this option is a hint, applications that want to* verify what loopback mode is set to should call* {@link #getLoopbackMode()}* @param disable {@code true} to disable the LoopbackMode* @throws SocketException if an error occurs while setting the value* @since 1.4* @see #getLoopbackMode*/public void setLoopbackMode(boolean disable) throws SocketException {getImpl().setOption(SocketOptions.IP_MULTICAST_LOOP, Boolean.valueOf(disable));}/*** Get the setting for local loopback of multicast datagrams.** @throws SocketException if an error occurs while getting the value* @return true if the LoopbackMode has been disabled* @since 1.4* @see #setLoopbackMode*/public boolean getLoopbackMode() throws SocketException {return ((Boolean)getImpl().getOption(SocketOptions.IP_MULTICAST_LOOP)).booleanValue();}/*** Sends a datagram packet to the destination, with a TTL (time-* to-live) other than the default for the socket. This method* need only be used in instances where a particular TTL is desired;* otherwise it is preferable to set a TTL once on the socket, and* use that default TTL for all packets. This method does <B>not* </B> alter the default TTL for the socket. Its behavior may be* affected by {@code setInterface}.** <p>If there is a security manager, this method first performs some* security checks. First, if {@code p.getAddress().isMulticastAddress()}* is true, this method calls the* security manager's {@code checkMulticast} method* with {@code p.getAddress()} and {@code ttl} as its arguments.* If the evaluation of that expression is false,* this method instead calls the security manager's* {@code checkConnect} method with arguments* {@code p.getAddress().getHostAddress()} and* {@code p.getPort()}. Each call to a security manager method* could result in a SecurityException if the operation is not allowed.** @param p is the packet to be sent. The packet should contain* the destination multicast ip address and the data to be sent.* One does not need to be the member of the group to send* packets to a destination multicast address.* @param ttl optional time to live for multicast packet.* default ttl is 1.** @exception IOException is raised if an error occurs i.e* error while setting ttl.* @exception SecurityException if a security manager exists and its* {@code checkMulticast} or {@code checkConnect}* method doesn't allow the send.** @deprecated Use the following code or its equivalent instead:* ......* int ttl = mcastSocket.getTimeToLive();* mcastSocket.setTimeToLive(newttl);* mcastSocket.send(p);* mcastSocket.setTimeToLive(ttl);* ......** @see DatagramSocket#send* @see DatagramSocket#receive* @see SecurityManager#checkMulticast(java.net.InetAddress, byte)* @see SecurityManager#checkConnect*/@Deprecatedpublic void send(DatagramPacket p, byte ttl)throws IOException {if (isClosed())throw new SocketException("Socket is closed");checkAddress(p.getAddress(), "send");synchronized(ttlLock) {synchronized(p) {if (connectState == ST_NOT_CONNECTED) {// Security manager makes sure that the multicast address// is allowed one and that the ttl used is less// than the allowed maxttl.SecurityManager security = System.getSecurityManager();if (security != null) {if (p.getAddress().isMulticastAddress()) {security.checkMulticast(p.getAddress(), ttl);} else {security.checkConnect(p.getAddress().getHostAddress(),p.getPort());}}} else {// we're connectedInetAddress packetAddress = null;packetAddress = p.getAddress();if (packetAddress == null) {p.setAddress(connectedAddress);p.setPort(connectedPort);} else if ((!packetAddress.equals(connectedAddress)) ||p.getPort() != connectedPort) {throw new SecurityException("connected address and packet address" +" differ");}}byte dttl = getTTL();try {if (ttl != dttl) {// set the ttlgetImpl().setTTL(ttl);}// call the datagram method to sendgetImpl().send(p);} finally {// set it back to defaultif (ttl != dttl) {getImpl().setTTL(dttl);}}} // synch p} //synch ttl} //methodprivate static Set<SocketOption<?>> options;private static boolean optionsSet = false;@Overridepublic Set<SocketOption<?>> supportedOptions() {synchronized (MulticastSocket.class) {if (optionsSet) {return options;}try {DatagramSocketImpl impl = getImpl();options = Collections.unmodifiableSet(impl.supportedOptions());} catch (SocketException ex) {options = Collections.emptySet();}optionsSet = true;return options;}}}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。