MulticastSocketpublic class MulticastSocket extends DatagramSocket 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.
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 224.0.0.0 to 239.255.255.255 ,
inclusive. The address 224.0.0.0 is reserved and should not be used.
One would join a multicast group by first creating a MulticastSocket
with the desired port, then invoking the
joinGroup(InetAddress groupAddr)
method:
// 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);
When one sends a message to a multicast group, all 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.
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.
Multiple MulticastSocket's may subscribe to a multicast group
and port concurrently, and they will all receive group datagrams.
Currently applets are not allowed to use multicast sockets. |
Fields Summary |
---|
private Object | ttlLockThe lock on the socket's TTL. This is for set/getTTL and
send(packet,ttl). | private Object | infLockThe lock on the socket's interface - used by setInterface
and getInterface | private InetAddress | infAddressThe "last" interface set by setInterface on this MulticastSocket |
Constructors Summary |
---|
public MulticastSocket()Create a multicast socket.
If there is a security manager,
its checkListen method is first called
with 0 as its argument to ensure the operation is allowed.
This could result in a SecurityException.
When the socket is created the
{@link DatagramSocket#setReuseAddress(boolean)} method is
called to enable the SO_REUSEADDR socket option.
this(new InetSocketAddress(0));
| public MulticastSocket(int port)Create a multicast socket and bind it to a specific port.
If there is a security manager,
its checkListen method is first called
with the port argument
as its argument to ensure the operation is allowed.
This could result in a SecurityException.
When the socket is created the
{@link DatagramSocket#setReuseAddress(boolean)} method is
called to enable the SO_REUSEADDR socket option.
this(new InetSocketAddress(port));
| public MulticastSocket(SocketAddress bindaddr)Create a MulticastSocket bound to the specified socket address.
Or, if the address is null , create an unbound socket.
If there is a security manager,
its checkListen method is first called
with the SocketAddress port as its argument to ensure the operation is allowed.
This could result in a SecurityException.
When the socket is created the
{@link DatagramSocket#setReuseAddress(boolean)} method is
called to enable the SO_REUSEADDR socket option.
super((SocketAddress) null);
// Enable SO_REUSEADDR before binding
setReuseAddress(true);
if (bindaddr != null) {
bind(bindaddr);
}
|
Methods Summary |
---|
public java.net.InetAddress | getInterface()Retrieve the address of the network interface used for
multicast packets.
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 addrs = ni.getInetAddresses();
while (addrs.hasMoreElements()) {
InetAddress addr = (InetAddress)(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;
}
}
| public boolean | getLoopbackMode()Get the setting for local loopback of multicast datagrams.
return ((Boolean)getImpl().getOption(SocketOptions.IP_MULTICAST_LOOP)).booleanValue();
| public java.net.NetworkInterface | getNetworkInterface()Get the multicast network interface set.
NetworkInterface ni
= (NetworkInterface)getImpl().getOption(SocketOptions.IP_MULTICAST_IF2);
if (ni.getIndex() == 0) {
InetAddress[] addrs = new InetAddress[1];
addrs[0] = InetAddress.anyLocalAddress();
return new NetworkInterface(addrs[0].getHostName(), 0, addrs);
} else {
return ni;
}
| public byte | getTTL()Get the default time-to-live for multicast packets sent out on
the socket.
if (isClosed())
throw new SocketException("Socket is closed");
return getImpl().getTTL();
| public int | getTimeToLive()Get the default time-to-live for multicast packets sent out on
the socket.
if (isClosed())
throw new SocketException("Socket is closed");
return getImpl().getTimeToLive();
| public void | joinGroup(java.net.SocketAddress mcastaddr, java.net.NetworkInterface netIf)Joins the specified multicast group at the specified interface.
If there is a security manager, this method first
calls its checkMulticast method
with the mcastaddr argument
as its argument.
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();
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);
| public void | joinGroup(java.net.InetAddress mcastaddr)Joins a multicast group. Its behavior may be affected by
setInterface or setNetworkInterface .
If there is a security manager, this method first
calls its checkMulticast method
with the mcastaddr argument
as its argument.
if (isClosed()) {
throw new SocketException("Socket is closed");
}
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkMulticast(mcastaddr);
}
if (!mcastaddr.isMulticastAddress()) {
throw new SocketException("Not a multicast address");
}
getImpl().join(mcastaddr);
| public void | leaveGroup(java.net.SocketAddress mcastaddr, java.net.NetworkInterface netIf)Leave a multicast group on a specified local interface.
If there is a security manager, this method first
calls its checkMulticast method
with the mcastaddr argument
as its argument.
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();
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);
| public void | leaveGroup(java.net.InetAddress mcastaddr)Leave a multicast group. Its behavior may be affected by
setInterface or setNetworkInterface .
If there is a security manager, this method first
calls its checkMulticast method
with the mcastaddr argument
as its argument.
if (isClosed()) {
throw new SocketException("Socket is closed");
}
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkMulticast(mcastaddr);
}
if (!mcastaddr.isMulticastAddress()) {
throw new SocketException("Not a multicast address");
}
getImpl().leave(mcastaddr);
| public void | send(java.net.DatagramPacket p, byte ttl)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 not
alter the default TTL for the socket. Its behavior may be
affected by setInterface .
If there is a security manager, this method first performs some
security checks. First, if p.getAddress().isMulticastAddress()
is true, this method calls the
security manager's checkMulticast method
with p.getAddress() and ttl as its arguments.
If the evaluation of that expression is false,
this method instead calls the security manager's
checkConnect method with arguments
p.getAddress().getHostAddress() and
p.getPort() . Each call to a security manager method
could result in a SecurityException if the operation is not allowed.
if (isClosed())
throw new SocketException("Socket is closed");
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 connected
InetAddress 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 ttl
getImpl().setTTL(ttl);
}
// call the datagram method to send
getImpl().send(p);
} finally {
// set it back to default
if (ttl != dttl) {
getImpl().setTTL(dttl);
}
}
} // synch p
} //synch ttl
| public void | setInterface(java.net.InetAddress inf)Set the multicast network interface used by methods
whose behavior would be affected by the value of the
network interface. Useful for multihomed hosts.
if (isClosed()) {
throw new SocketException("Socket is closed");
}
synchronized (infLock) {
getImpl().setOption(SocketOptions.IP_MULTICAST_IF, inf);
infAddress = inf;
}
| public void | setLoopbackMode(boolean disable)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.
Because this option is a hint, applications that want to
verify what loopback mode is set to should call
{@link #getLoopbackMode()}
getImpl().setOption(SocketOptions.IP_MULTICAST_LOOP, Boolean.valueOf(disable));
| public void | setNetworkInterface(java.net.NetworkInterface netIf)Specify the network interface for outgoing multicast datagrams
sent on this socket.
synchronized (infLock) {
getImpl().setOption(SocketOptions.IP_MULTICAST_IF2, netIf);
infAddress = null;
}
| public void | setTTL(byte ttl)Set the default time-to-live for multicast packets sent out
on this MulticastSocket in order to control the
scope of the multicasts.
The ttl is an unsigned 8-bit quantity, and so must be
in the range 0 <= ttl <= 0xFF .
if (isClosed())
throw new SocketException("Socket is closed");
getImpl().setTTL(ttl);
| public void | setTimeToLive(int ttl)Set the default time-to-live for multicast packets sent out
on this MulticastSocket in order to control the
scope of the multicasts.
The ttl must be in the range 0 <= ttl <=
255 or an IllegalArgumentException will be thrown.
if (ttl < 0 || ttl > 255) {
throw new IllegalArgumentException("ttl out of range");
}
if (isClosed())
throw new SocketException("Socket is closed");
getImpl().setTimeToLive(ttl);
|
|