1 /*
2 * Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
86 class MulticastSocket extends DatagramSocket {
87
88 /**
89 * Used on some platforms to record if an outgoing interface
90 * has been set for this socket.
91 */
92 private boolean interfaceSet;
93
94 /**
95 * Create a multicast socket.
96 *
97 * <p>
98 * If there is a security manager, its {@code checkListen} method is first
99 * called with 0 as its argument to ensure the operation is allowed. This
100 * could result in a SecurityException.
101 * <p>
102 * When the socket is created the
103 * {@link DatagramSocket#setReuseAddress(boolean)} method is called to
104 * enable the SO_REUSEADDR socket option.
105 *
106 * @exception IOException if an I/O exception occurs while creating the
107 * MulticastSocket
108 * @exception SecurityException if a security manager exists and its
109 * {@code checkListen} method doesn't allow the operation.
110 * @see SecurityManager#checkListen
111 * @see java.net.DatagramSocket#setReuseAddress(boolean)
112 * @see java.net.DatagramSocketImpl#setOption(SocketOption, Object)
113 */
114 public MulticastSocket() throws IOException {
115 this(new InetSocketAddress(0));
116 }
117
118 /**
119 * Create a multicast socket and bind it to a specific port.
120 *
121 * <p>If there is a security manager,
122 * its {@code checkListen} method is first called
123 * with the {@code port} argument
124 * as its argument to ensure the operation is allowed.
125 * This could result in a SecurityException.
126 * <p>
127 * When the socket is created the
128 * {@link DatagramSocket#setReuseAddress(boolean)} method is
129 * called to enable the SO_REUSEADDR socket option.
130 *
131 * @param port port to use
132 * @exception IOException if an I/O exception occurs
133 * while creating the MulticastSocket
134 * @exception SecurityException if a security manager exists and its
135 * {@code checkListen} method doesn't allow the operation.
136 * @see SecurityManager#checkListen
137 * @see java.net.DatagramSocket#setReuseAddress(boolean)
138 */
139 public MulticastSocket(int port) throws IOException {
140 this(new InetSocketAddress(port));
141 }
142
143 /**
144 * Create a MulticastSocket bound to the specified socket address.
145 * <p>
146 * Or, if the address is {@code null}, create an unbound socket.
147 *
148 * <p>If there is a security manager,
149 * its {@code checkListen} method is first called
150 * with the SocketAddress port as its argument to ensure the operation is allowed.
151 * This could result in a SecurityException.
152 * <p>
153 * When the socket is created the
154 * {@link DatagramSocket#setReuseAddress(boolean)} method is
155 * called to enable the SO_REUSEADDR socket option.
156 *
157 * @param bindaddr Socket address to bind to, or {@code null} for
158 * an unbound socket.
159 * @exception IOException if an I/O exception occurs
160 * while creating the MulticastSocket
161 * @exception SecurityException if a security manager exists and its
162 * {@code checkListen} method doesn't allow the operation.
163 * @see SecurityManager#checkListen
164 * @see java.net.DatagramSocket#setReuseAddress(boolean)
165 *
166 * @since 1.4
167 */
168 public MulticastSocket(SocketAddress bindaddr) throws IOException {
169 super((SocketAddress) null);
170
171 // Enable SO_REUSEADDR before binding
172 setReuseAddress(true);
173
174 if (bindaddr != null) {
175 try {
176 bind(bindaddr);
177 } finally {
178 if (!isBound()) {
179 close();
180 }
181 }
192 * The lock on the socket's interface - used by setInterface
193 * and getInterface
194 */
195 private Object infLock = new Object();
196
197 /**
198 * The "last" interface set by setInterface on this MulticastSocket
199 */
200 private InetAddress infAddress = null;
201
202
203 /**
204 * Set the default time-to-live for multicast packets sent out
205 * on this {@code MulticastSocket} in order to control the
206 * scope of the multicasts.
207 *
208 * <p>The ttl is an <b>unsigned</b> 8-bit quantity, and so <B>must</B> be
209 * in the range {@code 0 <= ttl <= 0xFF }.
210 *
211 * @param ttl the time-to-live
212 * @exception IOException if an I/O exception occurs
213 * while setting the default time-to-live value
214 * @deprecated use the setTimeToLive method instead, which uses
215 * <b>int</b> instead of <b>byte</b> as the type for ttl.
216 * @see #getTTL()
217 */
218 @Deprecated
219 public void setTTL(byte ttl) throws IOException {
220 if (isClosed())
221 throw new SocketException("Socket is closed");
222 getImpl().setTTL(ttl);
223 }
224
225 /**
226 * Set the default time-to-live for multicast packets sent out
227 * on this {@code MulticastSocket} in order to control the
228 * scope of the multicasts.
229 *
230 * <P> The ttl <B>must</B> be in the range {@code 0 <= ttl <=
231 * 255} or an {@code IllegalArgumentException} will be thrown.
232 * Multicast packets sent with a TTL of {@code 0} are not transmitted
237 *
238 * @throws IOException
239 * if an I/O exception occurs while setting the
240 * default time-to-live value
241 *
242 * @see #getTimeToLive()
243 */
244 public void setTimeToLive(int ttl) throws IOException {
245 if (ttl < 0 || ttl > 255) {
246 throw new IllegalArgumentException("ttl out of range");
247 }
248 if (isClosed())
249 throw new SocketException("Socket is closed");
250 getImpl().setTimeToLive(ttl);
251 }
252
253 /**
254 * Get the default time-to-live for multicast packets sent out on
255 * the socket.
256 *
257 * @exception IOException if an I/O exception occurs
258 * while getting the default time-to-live value
259 * @return the default time-to-live value
260 * @deprecated use the getTimeToLive method instead, which returns
261 * an <b>int</b> instead of a <b>byte</b>.
262 * @see #setTTL(byte)
263 */
264 @Deprecated
265 public byte getTTL() throws IOException {
266 if (isClosed())
267 throw new SocketException("Socket is closed");
268 return getImpl().getTTL();
269 }
270
271 /**
272 * Get the default time-to-live for multicast packets sent out on
273 * the socket.
274 * @exception IOException if an I/O exception occurs while
275 * getting the default time-to-live value
276 * @return the default time-to-live value
277 * @see #setTimeToLive(int)
278 */
279 public int getTimeToLive() throws IOException {
280 if (isClosed())
281 throw new SocketException("Socket is closed");
282 return getImpl().getTimeToLive();
283 }
284
285 /**
286 * Joins a multicast group. Its behavior may be affected by
287 * {@code setInterface} or {@code setNetworkInterface}.
288 *
289 * <p>If there is a security manager, this method first
290 * calls its {@code checkMulticast} method
291 * with the {@code mcastaddr} argument
292 * as its argument.
293 *
294 * @param mcastaddr is the multicast address to join
295 *
296 * @exception IOException if there is an error joining, or when the address
297 * is not a multicast address, or the platform does not support
298 * multicasting
299 * @exception SecurityException if a security manager exists and its
300 * {@code checkMulticast} method doesn't allow the join.
301 *
302 * @see SecurityManager#checkMulticast(InetAddress)
303 */
304 public void joinGroup(InetAddress mcastaddr) throws IOException {
305 if (isClosed()) {
306 throw new SocketException("Socket is closed");
307 }
308
309 checkAddress(mcastaddr, "joinGroup");
310 SecurityManager security = System.getSecurityManager();
311 if (security != null) {
312 security.checkMulticast(mcastaddr);
313 }
314
315 if (!mcastaddr.isMulticastAddress()) {
316 throw new SocketException("Not a multicast address");
317 }
318
319 /**
322 */
323 NetworkInterface defaultInterface = NetworkInterface.getDefault();
324
325 if (!interfaceSet && defaultInterface != null) {
326 setNetworkInterface(defaultInterface);
327 }
328
329 getImpl().join(mcastaddr);
330 }
331
332 /**
333 * Leave a multicast group. Its behavior may be affected by
334 * {@code setInterface} or {@code setNetworkInterface}.
335 *
336 * <p>If there is a security manager, this method first
337 * calls its {@code checkMulticast} method
338 * with the {@code mcastaddr} argument
339 * as its argument.
340 *
341 * @param mcastaddr is the multicast address to leave
342 * @exception IOException if there is an error leaving
343 * or when the address is not a multicast address.
344 * @exception SecurityException if a security manager exists and its
345 * {@code checkMulticast} method doesn't allow the operation.
346 *
347 * @see SecurityManager#checkMulticast(InetAddress)
348 */
349 public void leaveGroup(InetAddress mcastaddr) throws IOException {
350 if (isClosed()) {
351 throw new SocketException("Socket is closed");
352 }
353
354 checkAddress(mcastaddr, "leaveGroup");
355 SecurityManager security = System.getSecurityManager();
356 if (security != null) {
357 security.checkMulticast(mcastaddr);
358 }
359
360 if (!mcastaddr.isMulticastAddress()) {
361 throw new SocketException("Not a multicast address");
362 }
363
364 getImpl().leave(mcastaddr);
365 }
366
367 /**
368 * Joins the specified multicast group at the specified interface.
369 *
370 * <p>If there is a security manager, this method first
371 * calls its {@code checkMulticast} method
372 * with the {@code mcastaddr} argument
373 * as its argument.
374 *
375 * @param mcastaddr is the multicast address to join
376 * @param netIf specifies the local interface to receive multicast
377 * datagram packets, or <i>null</i> to defer to the interface set by
378 * {@link MulticastSocket#setInterface(InetAddress)} or
379 * {@link MulticastSocket#setNetworkInterface(NetworkInterface)}
380 *
381 * @exception IOException if there is an error joining, or when the address
382 * is not a multicast address, or the platform does not support
383 * multicasting
384 * @exception SecurityException if a security manager exists and its
385 * {@code checkMulticast} method doesn't allow the join.
386 * @throws IllegalArgumentException if mcastaddr is null or is a
387 * SocketAddress subclass not supported by this socket
388 *
389 * @see SecurityManager#checkMulticast(InetAddress)
390 * @since 1.4
391 */
392 public void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf)
393 throws IOException {
394 if (isClosed())
395 throw new SocketException("Socket is closed");
396
397 if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress))
398 throw new IllegalArgumentException("Unsupported address type");
399
400 if (oldImpl)
401 throw new UnsupportedOperationException();
402
403 checkAddress(((InetSocketAddress)mcastaddr).getAddress(), "joinGroup");
404 SecurityManager security = System.getSecurityManager();
409 if (!((InetSocketAddress)mcastaddr).getAddress().isMulticastAddress()) {
410 throw new SocketException("Not a multicast address");
411 }
412
413 getImpl().joinGroup(mcastaddr, netIf);
414 }
415
416 /**
417 * Leave a multicast group on a specified local interface.
418 *
419 * <p>If there is a security manager, this method first
420 * calls its {@code checkMulticast} method
421 * with the {@code mcastaddr} argument
422 * as its argument.
423 *
424 * @param mcastaddr is the multicast address to leave
425 * @param netIf specifies the local interface or <i>null</i> to defer
426 * to the interface set by
427 * {@link MulticastSocket#setInterface(InetAddress)} or
428 * {@link MulticastSocket#setNetworkInterface(NetworkInterface)}
429 * @exception IOException if there is an error leaving
430 * or when the address is not a multicast address.
431 * @exception SecurityException if a security manager exists and its
432 * {@code checkMulticast} method doesn't allow the operation.
433 * @throws IllegalArgumentException if mcastaddr is null or is a
434 * SocketAddress subclass not supported by this socket
435 *
436 * @see SecurityManager#checkMulticast(InetAddress)
437 * @since 1.4
438 */
439 public void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf)
440 throws IOException {
441 if (isClosed())
442 throw new SocketException("Socket is closed");
443
444 if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress))
445 throw new IllegalArgumentException("Unsupported address type");
446
447 if (oldImpl)
448 throw new UnsupportedOperationException();
449
450 checkAddress(((InetSocketAddress)mcastaddr).getAddress(), "leaveGroup");
451 SecurityManager security = System.getSecurityManager();
452 if (security != null) {
453 security.checkMulticast(((InetSocketAddress)mcastaddr).getAddress());
454 }
455
456 if (!((InetSocketAddress)mcastaddr).getAddress().isMulticastAddress()) {
457 throw new SocketException("Not a multicast address");
458 }
459
460 getImpl().leaveGroup(mcastaddr, netIf);
461 }
462
463 /**
464 * Set the multicast network interface used by methods
465 * whose behavior would be affected by the value of the
466 * network interface. Useful for multihomed hosts.
467 * @param inf the InetAddress
468 * @exception SocketException if there is an error in
469 * the underlying protocol, such as a TCP error.
470 * @see #getInterface()
471 */
472 public void setInterface(InetAddress inf) throws SocketException {
473 if (isClosed()) {
474 throw new SocketException("Socket is closed");
475 }
476 checkAddress(inf, "setInterface");
477 synchronized (infLock) {
478 getImpl().setOption(SocketOptions.IP_MULTICAST_IF, inf);
479 infAddress = inf;
480 interfaceSet = true;
481 }
482 }
483
484 /**
485 * Retrieve the address of the network interface used for
486 * multicast packets.
487 *
488 * @return An {@code InetAddress} representing
489 * the address of the network interface used for
490 * multicast packets.
491 *
492 * @exception SocketException if there is an error in
493 * the underlying protocol, such as a TCP error.
494 *
495 * @see #setInterface(java.net.InetAddress)
496 */
497 public InetAddress getInterface() throws SocketException {
498 if (isClosed()) {
499 throw new SocketException("Socket is closed");
500 }
501 synchronized (infLock) {
502 InetAddress ia =
503 (InetAddress)getImpl().getOption(SocketOptions.IP_MULTICAST_IF);
504
505 /**
506 * No previous setInterface or interface can be
507 * set using setNetworkInterface
508 */
509 if (infAddress == null) {
510 return ia;
511 }
512
532 }
533 }
534
535 /**
536 * No match so reset infAddress to indicate that the
537 * interface has changed via means
538 */
539 infAddress = null;
540 return ia;
541 } catch (Exception e) {
542 return ia;
543 }
544 }
545 }
546
547 /**
548 * Specify the network interface for outgoing multicast datagrams
549 * sent on this socket.
550 *
551 * @param netIf the interface
552 * @exception SocketException if there is an error in
553 * the underlying protocol, such as a TCP error.
554 * @see #getNetworkInterface()
555 * @since 1.4
556 */
557 public void setNetworkInterface(NetworkInterface netIf)
558 throws SocketException {
559
560 synchronized (infLock) {
561 getImpl().setOption(SocketOptions.IP_MULTICAST_IF2, netIf);
562 infAddress = null;
563 interfaceSet = true;
564 }
565 }
566
567 /**
568 * Get the multicast network interface set.
569 *
570 * @exception SocketException if there is an error in
571 * the underlying protocol, such as a TCP error.
572 * @return the multicast {@code NetworkInterface} currently set
573 * @see #setNetworkInterface(NetworkInterface)
574 * @since 1.4
575 */
576 public NetworkInterface getNetworkInterface() throws SocketException {
577 NetworkInterface ni
578 = (NetworkInterface)getImpl().getOption(SocketOptions.IP_MULTICAST_IF2);
579 if ((ni.getIndex() == 0) || (ni.getIndex() == -1)) {
580 InetAddress[] addrs = new InetAddress[1];
581 addrs[0] = InetAddress.anyLocalAddress();
582 return new NetworkInterface(addrs[0].getHostName(), 0, addrs);
583 } else {
584 return ni;
585 }
586 }
587
588 /**
589 * Disable/Enable local loopback of multicast datagrams
590 * The option is used by the platform's networking code as a hint
626 *
627 * <p>If there is a security manager, this method first performs some
628 * security checks. First, if {@code p.getAddress().isMulticastAddress()}
629 * is true, this method calls the
630 * security manager's {@code checkMulticast} method
631 * with {@code p.getAddress()} and {@code ttl} as its arguments.
632 * If the evaluation of that expression is false,
633 * this method instead calls the security manager's
634 * {@code checkConnect} method with arguments
635 * {@code p.getAddress().getHostAddress()} and
636 * {@code p.getPort()}. Each call to a security manager method
637 * could result in a SecurityException if the operation is not allowed.
638 *
639 * @param p is the packet to be sent. The packet should contain
640 * the destination multicast ip address and the data to be sent.
641 * One does not need to be the member of the group to send
642 * packets to a destination multicast address.
643 * @param ttl optional time to live for multicast packet.
644 * default ttl is 1.
645 *
646 * @exception IOException is raised if an error occurs i.e
647 * error while setting ttl.
648 * @exception SecurityException if a security manager exists and its
649 * {@code checkMulticast} or {@code checkConnect}
650 * method doesn't allow the send.
651 *
652 * @deprecated Use the following code or its equivalent instead:
653 * ......
654 * int ttl = mcastSocket.getTimeToLive();
655 * mcastSocket.setTimeToLive(newttl);
656 * mcastSocket.send(p);
657 * mcastSocket.setTimeToLive(ttl);
658 * ......
659 *
660 * @see DatagramSocket#send
661 * @see DatagramSocket#receive
662 * @see SecurityManager#checkMulticast(java.net.InetAddress, byte)
663 * @see SecurityManager#checkConnect
664 */
665 @Deprecated
666 public void send(DatagramPacket p, byte ttl)
667 throws IOException {
668 if (isClosed())
|
1 /*
2 * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
86 class MulticastSocket extends DatagramSocket {
87
88 /**
89 * Used on some platforms to record if an outgoing interface
90 * has been set for this socket.
91 */
92 private boolean interfaceSet;
93
94 /**
95 * Create a multicast socket.
96 *
97 * <p>
98 * If there is a security manager, its {@code checkListen} method is first
99 * called with 0 as its argument to ensure the operation is allowed. This
100 * could result in a SecurityException.
101 * <p>
102 * When the socket is created the
103 * {@link DatagramSocket#setReuseAddress(boolean)} method is called to
104 * enable the SO_REUSEADDR socket option.
105 *
106 * @throws IOException if an I/O exception occurs while creating the
107 * MulticastSocket
108 * @throws SecurityException if a security manager exists and its
109 * {@code checkListen} method doesn't allow the operation.
110 * @see SecurityManager#checkListen
111 * @see java.net.DatagramSocket#setReuseAddress(boolean)
112 * @see java.net.DatagramSocketImpl#setOption(SocketOption, Object)
113 */
114 public MulticastSocket() throws IOException {
115 this(new InetSocketAddress(0));
116 }
117
118 /**
119 * Create a multicast socket and bind it to a specific port.
120 *
121 * <p>If there is a security manager,
122 * its {@code checkListen} method is first called
123 * with the {@code port} argument
124 * as its argument to ensure the operation is allowed.
125 * This could result in a SecurityException.
126 * <p>
127 * When the socket is created the
128 * {@link DatagramSocket#setReuseAddress(boolean)} method is
129 * called to enable the SO_REUSEADDR socket option.
130 *
131 * @param port port to use
132 * @throws IOException if an I/O exception occurs
133 * while creating the MulticastSocket
134 * @throws SecurityException if a security manager exists and its
135 * {@code checkListen} method doesn't allow the operation.
136 * @see SecurityManager#checkListen
137 * @see java.net.DatagramSocket#setReuseAddress(boolean)
138 */
139 public MulticastSocket(int port) throws IOException {
140 this(new InetSocketAddress(port));
141 }
142
143 /**
144 * Create a MulticastSocket bound to the specified socket address.
145 * <p>
146 * Or, if the address is {@code null}, create an unbound socket.
147 *
148 * <p>If there is a security manager,
149 * its {@code checkListen} method is first called
150 * with the SocketAddress port as its argument to ensure the operation is allowed.
151 * This could result in a SecurityException.
152 * <p>
153 * When the socket is created the
154 * {@link DatagramSocket#setReuseAddress(boolean)} method is
155 * called to enable the SO_REUSEADDR socket option.
156 *
157 * @param bindaddr Socket address to bind to, or {@code null} for
158 * an unbound socket.
159 * @throws IOException if an I/O exception occurs
160 * while creating the MulticastSocket
161 * @throws SecurityException if a security manager exists and its
162 * {@code checkListen} method doesn't allow the operation.
163 * @see SecurityManager#checkListen
164 * @see java.net.DatagramSocket#setReuseAddress(boolean)
165 *
166 * @since 1.4
167 */
168 public MulticastSocket(SocketAddress bindaddr) throws IOException {
169 super((SocketAddress) null);
170
171 // Enable SO_REUSEADDR before binding
172 setReuseAddress(true);
173
174 if (bindaddr != null) {
175 try {
176 bind(bindaddr);
177 } finally {
178 if (!isBound()) {
179 close();
180 }
181 }
192 * The lock on the socket's interface - used by setInterface
193 * and getInterface
194 */
195 private Object infLock = new Object();
196
197 /**
198 * The "last" interface set by setInterface on this MulticastSocket
199 */
200 private InetAddress infAddress = null;
201
202
203 /**
204 * Set the default time-to-live for multicast packets sent out
205 * on this {@code MulticastSocket} in order to control the
206 * scope of the multicasts.
207 *
208 * <p>The ttl is an <b>unsigned</b> 8-bit quantity, and so <B>must</B> be
209 * in the range {@code 0 <= ttl <= 0xFF }.
210 *
211 * @param ttl the time-to-live
212 * @throws IOException if an I/O exception occurs
213 * while setting the default time-to-live value
214 * @deprecated use the setTimeToLive method instead, which uses
215 * <b>int</b> instead of <b>byte</b> as the type for ttl.
216 * @see #getTTL()
217 */
218 @Deprecated
219 public void setTTL(byte ttl) throws IOException {
220 if (isClosed())
221 throw new SocketException("Socket is closed");
222 getImpl().setTTL(ttl);
223 }
224
225 /**
226 * Set the default time-to-live for multicast packets sent out
227 * on this {@code MulticastSocket} in order to control the
228 * scope of the multicasts.
229 *
230 * <P> The ttl <B>must</B> be in the range {@code 0 <= ttl <=
231 * 255} or an {@code IllegalArgumentException} will be thrown.
232 * Multicast packets sent with a TTL of {@code 0} are not transmitted
237 *
238 * @throws IOException
239 * if an I/O exception occurs while setting the
240 * default time-to-live value
241 *
242 * @see #getTimeToLive()
243 */
244 public void setTimeToLive(int ttl) throws IOException {
245 if (ttl < 0 || ttl > 255) {
246 throw new IllegalArgumentException("ttl out of range");
247 }
248 if (isClosed())
249 throw new SocketException("Socket is closed");
250 getImpl().setTimeToLive(ttl);
251 }
252
253 /**
254 * Get the default time-to-live for multicast packets sent out on
255 * the socket.
256 *
257 * @throws IOException if an I/O exception occurs
258 * while getting the default time-to-live value
259 * @return the default time-to-live value
260 * @deprecated use the getTimeToLive method instead, which returns
261 * an <b>int</b> instead of a <b>byte</b>.
262 * @see #setTTL(byte)
263 */
264 @Deprecated
265 public byte getTTL() throws IOException {
266 if (isClosed())
267 throw new SocketException("Socket is closed");
268 return getImpl().getTTL();
269 }
270
271 /**
272 * Get the default time-to-live for multicast packets sent out on
273 * the socket.
274 * @throws IOException if an I/O exception occurs while
275 * getting the default time-to-live value
276 * @return the default time-to-live value
277 * @see #setTimeToLive(int)
278 */
279 public int getTimeToLive() throws IOException {
280 if (isClosed())
281 throw new SocketException("Socket is closed");
282 return getImpl().getTimeToLive();
283 }
284
285 /**
286 * Joins a multicast group. Its behavior may be affected by
287 * {@code setInterface} or {@code setNetworkInterface}.
288 *
289 * <p>If there is a security manager, this method first
290 * calls its {@code checkMulticast} method
291 * with the {@code mcastaddr} argument
292 * as its argument.
293 *
294 * @param mcastaddr is the multicast address to join
295 *
296 * @throws IOException if there is an error joining, or when the address
297 * is not a multicast address, or the platform does not support
298 * multicasting
299 * @throws SecurityException if a security manager exists and its
300 * {@code checkMulticast} method doesn't allow the join.
301 *
302 * @see SecurityManager#checkMulticast(InetAddress)
303 */
304 public void joinGroup(InetAddress mcastaddr) throws IOException {
305 if (isClosed()) {
306 throw new SocketException("Socket is closed");
307 }
308
309 checkAddress(mcastaddr, "joinGroup");
310 SecurityManager security = System.getSecurityManager();
311 if (security != null) {
312 security.checkMulticast(mcastaddr);
313 }
314
315 if (!mcastaddr.isMulticastAddress()) {
316 throw new SocketException("Not a multicast address");
317 }
318
319 /**
322 */
323 NetworkInterface defaultInterface = NetworkInterface.getDefault();
324
325 if (!interfaceSet && defaultInterface != null) {
326 setNetworkInterface(defaultInterface);
327 }
328
329 getImpl().join(mcastaddr);
330 }
331
332 /**
333 * Leave a multicast group. Its behavior may be affected by
334 * {@code setInterface} or {@code setNetworkInterface}.
335 *
336 * <p>If there is a security manager, this method first
337 * calls its {@code checkMulticast} method
338 * with the {@code mcastaddr} argument
339 * as its argument.
340 *
341 * @param mcastaddr is the multicast address to leave
342 * @throws IOException if there is an error leaving
343 * or when the address is not a multicast address.
344 * @throws SecurityException if a security manager exists and its
345 * {@code checkMulticast} method doesn't allow the operation.
346 *
347 * @see SecurityManager#checkMulticast(InetAddress)
348 */
349 public void leaveGroup(InetAddress mcastaddr) throws IOException {
350 if (isClosed()) {
351 throw new SocketException("Socket is closed");
352 }
353
354 checkAddress(mcastaddr, "leaveGroup");
355 SecurityManager security = System.getSecurityManager();
356 if (security != null) {
357 security.checkMulticast(mcastaddr);
358 }
359
360 if (!mcastaddr.isMulticastAddress()) {
361 throw new SocketException("Not a multicast address");
362 }
363
364 getImpl().leave(mcastaddr);
365 }
366
367 /**
368 * Joins the specified multicast group at the specified interface.
369 *
370 * <p>If there is a security manager, this method first
371 * calls its {@code checkMulticast} method
372 * with the {@code mcastaddr} argument
373 * as its argument.
374 *
375 * @param mcastaddr is the multicast address to join
376 * @param netIf specifies the local interface to receive multicast
377 * datagram packets, or <i>null</i> to defer to the interface set by
378 * {@link MulticastSocket#setInterface(InetAddress)} or
379 * {@link MulticastSocket#setNetworkInterface(NetworkInterface)}
380 *
381 * @throws IOException if there is an error joining, or when the address
382 * is not a multicast address, or the platform does not support
383 * multicasting
384 * @throws SecurityException if a security manager exists and its
385 * {@code checkMulticast} method doesn't allow the join.
386 * @throws IllegalArgumentException if mcastaddr is null or is a
387 * SocketAddress subclass not supported by this socket
388 *
389 * @see SecurityManager#checkMulticast(InetAddress)
390 * @since 1.4
391 */
392 public void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf)
393 throws IOException {
394 if (isClosed())
395 throw new SocketException("Socket is closed");
396
397 if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress))
398 throw new IllegalArgumentException("Unsupported address type");
399
400 if (oldImpl)
401 throw new UnsupportedOperationException();
402
403 checkAddress(((InetSocketAddress)mcastaddr).getAddress(), "joinGroup");
404 SecurityManager security = System.getSecurityManager();
409 if (!((InetSocketAddress)mcastaddr).getAddress().isMulticastAddress()) {
410 throw new SocketException("Not a multicast address");
411 }
412
413 getImpl().joinGroup(mcastaddr, netIf);
414 }
415
416 /**
417 * Leave a multicast group on a specified local interface.
418 *
419 * <p>If there is a security manager, this method first
420 * calls its {@code checkMulticast} method
421 * with the {@code mcastaddr} argument
422 * as its argument.
423 *
424 * @param mcastaddr is the multicast address to leave
425 * @param netIf specifies the local interface or <i>null</i> to defer
426 * to the interface set by
427 * {@link MulticastSocket#setInterface(InetAddress)} or
428 * {@link MulticastSocket#setNetworkInterface(NetworkInterface)}
429 * @throws IOException if there is an error leaving
430 * or when the address is not a multicast address.
431 * @throws SecurityException if a security manager exists and its
432 * {@code checkMulticast} method doesn't allow the operation.
433 * @throws IllegalArgumentException if mcastaddr is null or is a
434 * SocketAddress subclass not supported by this socket
435 *
436 * @see SecurityManager#checkMulticast(InetAddress)
437 * @since 1.4
438 */
439 public void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf)
440 throws IOException {
441 if (isClosed())
442 throw new SocketException("Socket is closed");
443
444 if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress))
445 throw new IllegalArgumentException("Unsupported address type");
446
447 if (oldImpl)
448 throw new UnsupportedOperationException();
449
450 checkAddress(((InetSocketAddress)mcastaddr).getAddress(), "leaveGroup");
451 SecurityManager security = System.getSecurityManager();
452 if (security != null) {
453 security.checkMulticast(((InetSocketAddress)mcastaddr).getAddress());
454 }
455
456 if (!((InetSocketAddress)mcastaddr).getAddress().isMulticastAddress()) {
457 throw new SocketException("Not a multicast address");
458 }
459
460 getImpl().leaveGroup(mcastaddr, netIf);
461 }
462
463 /**
464 * Set the multicast network interface used by methods
465 * whose behavior would be affected by the value of the
466 * network interface. Useful for multihomed hosts.
467 * @param inf the InetAddress
468 * @throws SocketException if there is an error in
469 * the underlying protocol, such as a TCP error.
470 * @see #getInterface()
471 */
472 public void setInterface(InetAddress inf) throws SocketException {
473 if (isClosed()) {
474 throw new SocketException("Socket is closed");
475 }
476 checkAddress(inf, "setInterface");
477 synchronized (infLock) {
478 getImpl().setOption(SocketOptions.IP_MULTICAST_IF, inf);
479 infAddress = inf;
480 interfaceSet = true;
481 }
482 }
483
484 /**
485 * Retrieve the address of the network interface used for
486 * multicast packets.
487 *
488 * @return An {@code InetAddress} representing
489 * the address of the network interface used for
490 * multicast packets.
491 *
492 * @throws SocketException if there is an error in
493 * the underlying protocol, such as a TCP error.
494 *
495 * @see #setInterface(java.net.InetAddress)
496 */
497 public InetAddress getInterface() throws SocketException {
498 if (isClosed()) {
499 throw new SocketException("Socket is closed");
500 }
501 synchronized (infLock) {
502 InetAddress ia =
503 (InetAddress)getImpl().getOption(SocketOptions.IP_MULTICAST_IF);
504
505 /**
506 * No previous setInterface or interface can be
507 * set using setNetworkInterface
508 */
509 if (infAddress == null) {
510 return ia;
511 }
512
532 }
533 }
534
535 /**
536 * No match so reset infAddress to indicate that the
537 * interface has changed via means
538 */
539 infAddress = null;
540 return ia;
541 } catch (Exception e) {
542 return ia;
543 }
544 }
545 }
546
547 /**
548 * Specify the network interface for outgoing multicast datagrams
549 * sent on this socket.
550 *
551 * @param netIf the interface
552 * @throws SocketException if there is an error in
553 * the underlying protocol, such as a TCP error.
554 * @see #getNetworkInterface()
555 * @since 1.4
556 */
557 public void setNetworkInterface(NetworkInterface netIf)
558 throws SocketException {
559
560 synchronized (infLock) {
561 getImpl().setOption(SocketOptions.IP_MULTICAST_IF2, netIf);
562 infAddress = null;
563 interfaceSet = true;
564 }
565 }
566
567 /**
568 * Get the multicast network interface set.
569 *
570 * @throws SocketException if there is an error in
571 * the underlying protocol, such as a TCP error.
572 * @return the multicast {@code NetworkInterface} currently set
573 * @see #setNetworkInterface(NetworkInterface)
574 * @since 1.4
575 */
576 public NetworkInterface getNetworkInterface() throws SocketException {
577 NetworkInterface ni
578 = (NetworkInterface)getImpl().getOption(SocketOptions.IP_MULTICAST_IF2);
579 if ((ni.getIndex() == 0) || (ni.getIndex() == -1)) {
580 InetAddress[] addrs = new InetAddress[1];
581 addrs[0] = InetAddress.anyLocalAddress();
582 return new NetworkInterface(addrs[0].getHostName(), 0, addrs);
583 } else {
584 return ni;
585 }
586 }
587
588 /**
589 * Disable/Enable local loopback of multicast datagrams
590 * The option is used by the platform's networking code as a hint
626 *
627 * <p>If there is a security manager, this method first performs some
628 * security checks. First, if {@code p.getAddress().isMulticastAddress()}
629 * is true, this method calls the
630 * security manager's {@code checkMulticast} method
631 * with {@code p.getAddress()} and {@code ttl} as its arguments.
632 * If the evaluation of that expression is false,
633 * this method instead calls the security manager's
634 * {@code checkConnect} method with arguments
635 * {@code p.getAddress().getHostAddress()} and
636 * {@code p.getPort()}. Each call to a security manager method
637 * could result in a SecurityException if the operation is not allowed.
638 *
639 * @param p is the packet to be sent. The packet should contain
640 * the destination multicast ip address and the data to be sent.
641 * One does not need to be the member of the group to send
642 * packets to a destination multicast address.
643 * @param ttl optional time to live for multicast packet.
644 * default ttl is 1.
645 *
646 * @throws IOException is raised if an error occurs i.e
647 * error while setting ttl.
648 * @throws SecurityException if a security manager exists and its
649 * {@code checkMulticast} or {@code checkConnect}
650 * method doesn't allow the send.
651 *
652 * @deprecated Use the following code or its equivalent instead:
653 * ......
654 * int ttl = mcastSocket.getTimeToLive();
655 * mcastSocket.setTimeToLive(newttl);
656 * mcastSocket.send(p);
657 * mcastSocket.setTimeToLive(ttl);
658 * ......
659 *
660 * @see DatagramSocket#send
661 * @see DatagramSocket#receive
662 * @see SecurityManager#checkMulticast(java.net.InetAddress, byte)
663 * @see SecurityManager#checkConnect
664 */
665 @Deprecated
666 public void send(DatagramPacket p, byte ttl)
667 throws IOException {
668 if (isClosed())
|