History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/net/MulticastSocket.java (1 of 18352 files). Show all

Unified · Split

java/pkg/java/net/MulticastSocket.java+686−0
@@ -0,0 +1,686 @@
1+/*
2+ * Copyright (c) 1995, 2007, 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
23+ * questions.
24+ */
25+
26+package java.net;
27+
28+import java.io.IOException;
29+import java.io.InterruptedIOException;
30+import java.util.Enumeration;
31+
32+/**
33+ * The multicast datagram socket class is useful for sending
34+ * and receiving IP multicast packets. A MulticastSocket is
35+ * a (UDP) DatagramSocket, with additional capabilities for
36+ * joining "groups" of other multicast hosts on the internet.
37+ * <P>
38+ * A multicast group is specified by a class D IP address
39+ * and by a standard UDP port number. Class D IP addresses
40+ * are in the range <CODE>224.0.0.0</CODE> to <CODE>239.255.255.255</CODE>,
41+ * inclusive. The address 224.0.0.0 is reserved and should not be used.
42+ * <P>
43+ * One would join a multicast group by first creating a MulticastSocket
44+ * with the desired port, then invoking the
45+ * <CODE>joinGroup(InetAddress groupAddr)</CODE>
46+ * method:
47+ * <PRE>
48+ * // join a Multicast group and send the group salutations
49+ * ...
50+ * String msg = "Hello";
51+ * InetAddress group = InetAddress.getByName("228.5.6.7");
52+ * MulticastSocket s = new MulticastSocket(6789);
53+ * s.joinGroup(group);
54+ * DatagramPacket hi = new DatagramPacket(msg.getBytes(), msg.length(),
55+ * group, 6789);
56+ * s.send(hi);
57+ * // get their responses!
58+ * byte[] buf = new byte[1000];
59+ * DatagramPacket recv = new DatagramPacket(buf, buf.length);
60+ * s.receive(recv);
61+ * ...
62+ * // OK, I'm done talking - leave the group...
63+ * s.leaveGroup(group);
64+ * </PRE>
65+ *
66+ * When one sends a message to a multicast group, <B>all</B> subscribing
67+ * recipients to that host and port receive the message (within the
68+ * time-to-live range of the packet, see below). The socket needn't
69+ * be a member of the multicast group to send messages to it.
70+ * <P>
71+ * When a socket subscribes to a multicast group/port, it receives
72+ * datagrams sent by other hosts to the group/port, as do all other
73+ * members of the group and port. A socket relinquishes membership
74+ * in a group by the leaveGroup(InetAddress addr) method. <B>
75+ * Multiple MulticastSocket's</B> may subscribe to a multicast group
76+ * and port concurrently, and they will all receive group datagrams.
77+ * <P>
78+ * Currently applets are not allowed to use multicast sockets.
79+ *
80+ * @author Pavani Diwanji
81+ * @since JDK1.1
82+ */
83+public
84+class MulticastSocket extends DatagramSocket {
85+ /**
86+ * Create a multicast socket.
87+ *
88+ * <p>If there is a security manager,
89+ * its <code>checkListen</code> method is first called
90+ * with 0 as its argument to ensure the operation is allowed.
91+ * This could result in a SecurityException.
92+ * <p>
93+ * When the socket is created the
94+ * {@link DatagramSocket#setReuseAddress(boolean)} method is
95+ * called to enable the SO_REUSEADDR socket option.
96+ *
97+ * @exception IOException if an I/O exception occurs
98+ * while creating the MulticastSocket
99+ * @exception SecurityException if a security manager exists and its
100+ * <code>checkListen</code> method doesn't allow the operation.
101+ * @see SecurityManager#checkListen
102+ * @see java.net.DatagramSocket#setReuseAddress(boolean)
103+ */
104+ public MulticastSocket() throws IOException {
105+ this(new InetSocketAddress(0));
106+ }
107+
108+ /**
109+ * Create a multicast socket and bind it to a specific port.
110+ *
111+ * <p>If there is a security manager,
112+ * its <code>checkListen</code> method is first called
113+ * with the <code>port</code> argument
114+ * as its argument to ensure the operation is allowed.
115+ * This could result in a SecurityException.
116+ * <p>
117+ * When the socket is created the
118+ * {@link DatagramSocket#setReuseAddress(boolean)} method is
119+ * called to enable the SO_REUSEADDR socket option.
120+ *
121+ * @param port port to use
122+ * @exception IOException if an I/O exception occurs
123+ * while creating the MulticastSocket
124+ * @exception SecurityException if a security manager exists and its
125+ * <code>checkListen</code> method doesn't allow the operation.
126+ * @see SecurityManager#checkListen
127+ * @see java.net.DatagramSocket#setReuseAddress(boolean)
128+ */
129+ public MulticastSocket(int port) throws IOException {
130+ this(new InetSocketAddress(port));
131+ }
132+
133+ /**
134+ * Create a MulticastSocket bound to the specified socket address.
135+ * <p>
136+ * Or, if the address is <code>null</code>, create an unbound socket.
137+ * <p>
138+ * <p>If there is a security manager,
139+ * its <code>checkListen</code> method is first called
140+ * with the SocketAddress port as its argument to ensure the operation is allowed.
141+ * This could result in a SecurityException.
142+ * <p>
143+ * When the socket is created the
144+ * {@link DatagramSocket#setReuseAddress(boolean)} method is
145+ * called to enable the SO_REUSEADDR socket option.
146+ *
147+ * @param bindaddr Socket address to bind to, or <code>null</code> for
148+ * an unbound socket.
149+ * @exception IOException if an I/O exception occurs
150+ * while creating the MulticastSocket
151+ * @exception SecurityException if a security manager exists and its
152+ * <code>checkListen</code> method doesn't allow the operation.
153+ * @see SecurityManager#checkListen
154+ * @see java.net.DatagramSocket#setReuseAddress(boolean)
155+ *
156+ * @since 1.4
157+ */
158+ public MulticastSocket(SocketAddress bindaddr) throws IOException {
159+ super((SocketAddress) null);
160+
161+ // Enable SO_REUSEADDR before binding
162+ setReuseAddress(true);
163+
164+ if (bindaddr != null) {
165+ bind(bindaddr);
166+ }
167+ }
168+
169+ /**
170+ * The lock on the socket's TTL. This is for set/getTTL and
171+ * send(packet,ttl).
172+ */
173+ private Object ttlLock = new Object();
174+
175+ /**
176+ * The lock on the socket's interface - used by setInterface
177+ * and getInterface
178+ */
179+ private Object infLock = new Object();
180+
181+ /**
182+ * The "last" interface set by setInterface on this MulticastSocket
183+ */
184+ private InetAddress infAddress = null;
185+
186+
187+ /**
188+ * Set the default time-to-live for multicast packets sent out
189+ * on this <code>MulticastSocket</code> in order to control the
190+ * scope of the multicasts.
191+ *
192+ * <p>The ttl is an <b>unsigned</b> 8-bit quantity, and so <B>must</B> be
193+ * in the range <code> 0 <= ttl <= 0xFF </code>.
194+ *
195+ * @param ttl the time-to-live
196+ * @exception IOException if an I/O exception occurs
197+ * while setting the default time-to-live value
198+ * @deprecated use the setTimeToLive method instead, which uses
199+ * <b>int</b> instead of <b>byte</b> as the type for ttl.
200+ * @see #getTTL()
201+ */
202+ @Deprecated
203+ public void setTTL(byte ttl) throws IOException {
204+ if (isClosed())
205+ throw new SocketException("Socket is closed");
206+ getImpl().setTTL(ttl);
207+ }
208+
209+ /**
210+ * Set the default time-to-live for multicast packets sent out
211+ * on this {@code MulticastSocket} in order to control the
212+ * scope of the multicasts.
213+ *
214+ * <P> The ttl <B>must</B> be in the range {@code 0 <= ttl <=
215+ * 255} or an {@code IllegalArgumentException} will be thrown.
216+ * Multicast packets sent with a TTL of {@code 0} are not transmitted
217+ * on the network but may be delivered locally.
218+ *
219+ * @param ttl
220+ * the time-to-live
221+ *
222+ * @throws IOException
223+ * if an I/O exception occurs while setting the
224+ * default time-to-live value
225+ *
226+ * @see #getTimeToLive()
227+ */
228+ public void setTimeToLive(int ttl) throws IOException {
229+ if (ttl < 0 || ttl > 255) {
230+ throw new IllegalArgumentException("ttl out of range");
231+ }
232+ if (isClosed())
233+ throw new SocketException("Socket is closed");
234+ getImpl().setTimeToLive(ttl);
235+ }
236+
237+ /**
238+ * Get the default time-to-live for multicast packets sent out on
239+ * the socket.
240+ *
241+ * @exception IOException if an I/O exception occurs
242+ * while getting the default time-to-live value
243+ * @return the default time-to-live value
244+ * @deprecated use the getTimeToLive method instead, which returns
245+ * an <b>int</b> instead of a <b>byte</b>.
246+ * @see #setTTL(byte)
247+ */
248+ @Deprecated
249+ public byte getTTL() throws IOException {
250+ if (isClosed())
251+ throw new SocketException("Socket is closed");
252+ return getImpl().getTTL();
253+ }
254+
255+ /**
256+ * Get the default time-to-live for multicast packets sent out on
257+ * the socket.
258+ * @exception IOException if an I/O exception occurs while
259+ * getting the default time-to-live value
260+ * @return the default time-to-live value
261+ * @see #setTimeToLive(int)
262+ */
263+ public int getTimeToLive() throws IOException {
264+ if (isClosed())
265+ throw new SocketException("Socket is closed");
266+ return getImpl().getTimeToLive();
267+ }
268+
269+ /**
270+ * Joins a multicast group. Its behavior may be affected by
271+ * <code>setInterface</code> or <code>setNetworkInterface</code>.
272+ *
273+ * <p>If there is a security manager, this method first
274+ * calls its <code>checkMulticast</code> method
275+ * with the <code>mcastaddr</code> argument
276+ * as its argument.
277+ *
278+ * @param mcastaddr is the multicast address to join
279+ *
280+ * @exception IOException if there is an error joining
281+ * or when the address is not a multicast address.
282+ * @exception SecurityException if a security manager exists and its
283+ * <code>checkMulticast</code> method doesn't allow the join.
284+ *
285+ * @see SecurityManager#checkMulticast(InetAddress)
286+ */
287+ public void joinGroup(InetAddress mcastaddr) throws IOException {
288+ if (isClosed()) {
289+ throw new SocketException("Socket is closed");
290+ }
291+
292+ checkAddress(mcastaddr, "joinGroup");
293+ SecurityManager security = System.getSecurityManager();
294+ if (security != null) {
295+ security.checkMulticast(mcastaddr);
296+ }
297+
298+ if (!mcastaddr.isMulticastAddress()) {
299+ throw new SocketException("Not a multicast address");
300+ }
301+
302+ getImpl().join(mcastaddr);
303+ }
304+
305+ /**
306+ * Leave a multicast group. Its behavior may be affected by
307+ * <code>setInterface</code> or <code>setNetworkInterface</code>.
308+ *
309+ * <p>If there is a security manager, this method first
310+ * calls its <code>checkMulticast</code> method
311+ * with the <code>mcastaddr</code> argument
312+ * as its argument.
313+ *
314+ * @param mcastaddr is the multicast address to leave
315+ * @exception IOException if there is an error leaving
316+ * or when the address is not a multicast address.
317+ * @exception SecurityException if a security manager exists and its
318+ * <code>checkMulticast</code> method doesn't allow the operation.
319+ *
320+ * @see SecurityManager#checkMulticast(InetAddress)
321+ */
322+ public void leaveGroup(InetAddress mcastaddr) throws IOException {
323+ if (isClosed()) {
324+ throw new SocketException("Socket is closed");
325+ }
326+
327+ checkAddress(mcastaddr, "leaveGroup");
328+ SecurityManager security = System.getSecurityManager();
329+ if (security != null) {
330+ security.checkMulticast(mcastaddr);
331+ }
332+
333+ if (!mcastaddr.isMulticastAddress()) {
334+ throw new SocketException("Not a multicast address");
335+ }
336+
337+ getImpl().leave(mcastaddr);
338+ }
339+
340+ /**
341+ * Joins the specified multicast group at the specified interface.
342+ *
343+ * <p>If there is a security manager, this method first
344+ * calls its <code>checkMulticast</code> method
345+ * with the <code>mcastaddr</code> argument
346+ * as its argument.
347+ *
348+ * @param mcastaddr is the multicast address to join
349+ * @param netIf specifies the local interface to receive multicast
350+ * datagram packets, or <i>null</i> to defer to the interface set by
351+ * {@link MulticastSocket#setInterface(InetAddress)} or
352+ * {@link MulticastSocket#setNetworkInterface(NetworkInterface)}
353+ *
354+ * @exception IOException if there is an error joining
355+ * or when the address is not a multicast address.
356+ * @exception SecurityException if a security manager exists and its
357+ * <code>checkMulticast</code> method doesn't allow the join.
358+ * @throws IllegalArgumentException if mcastaddr is null or is a
359+ * SocketAddress subclass not supported by this socket
360+ *
361+ * @see SecurityManager#checkMulticast(InetAddress)
362+ * @since 1.4
363+ */
364+ public void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf)
365+ throws IOException {
366+ if (isClosed())
367+ throw new SocketException("Socket is closed");
368+
369+ if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress))
370+ throw new IllegalArgumentException("Unsupported address type");
371+
372+ if (oldImpl)
373+ throw new UnsupportedOperationException();
374+
375+ checkAddress(((InetSocketAddress)mcastaddr).getAddress(), "joinGroup");
376+ SecurityManager security = System.getSecurityManager();
377+ if (security != null) {
378+ security.checkMulticast(((InetSocketAddress)mcastaddr).getAddress());
379+ }
380+
381+ if (!((InetSocketAddress)mcastaddr).getAddress().isMulticastAddress()) {
382+ throw new SocketException("Not a multicast address");
383+ }
384+
385+ getImpl().joinGroup(mcastaddr, netIf);
386+ }
387+
388+ /**
389+ * Leave a multicast group on a specified local interface.
390+ *
391+ * <p>If there is a security manager, this method first
392+ * calls its <code>checkMulticast</code> method
393+ * with the <code>mcastaddr</code> argument
394+ * as its argument.
395+ *
396+ * @param mcastaddr is the multicast address to leave
397+ * @param netIf specifies the local interface or <i>null</i> to defer
398+ * to the interface set by
399+ * {@link MulticastSocket#setInterface(InetAddress)} or
400+ * {@link MulticastSocket#setNetworkInterface(NetworkInterface)}
401+ * @exception IOException if there is an error leaving
402+ * or when the address is not a multicast address.
403+ * @exception SecurityException if a security manager exists and its
404+ * <code>checkMulticast</code> method doesn't allow the operation.
405+ * @throws IllegalArgumentException if mcastaddr is null or is a
406+ * SocketAddress subclass not supported by this socket
407+ *
408+ * @see SecurityManager#checkMulticast(InetAddress)
409+ * @since 1.4
410+ */
411+ public void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf)
412+ throws IOException {
413+ if (isClosed())
414+ throw new SocketException("Socket is closed");
415+
416+ if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress))
417+ throw new IllegalArgumentException("Unsupported address type");
418+
419+ if (oldImpl)
420+ throw new UnsupportedOperationException();
421+
422+ checkAddress(((InetSocketAddress)mcastaddr).getAddress(), "leaveGroup");
423+ SecurityManager security = System.getSecurityManager();
424+ if (security != null) {
425+ security.checkMulticast(((InetSocketAddress)mcastaddr).getAddress());
426+ }
427+
428+ if (!((InetSocketAddress)mcastaddr).getAddress().isMulticastAddress()) {
429+ throw new SocketException("Not a multicast address");
430+ }
431+
432+ getImpl().leaveGroup(mcastaddr, netIf);
433+ }
434+
435+ /**
436+ * Set the multicast network interface used by methods
437+ * whose behavior would be affected by the value of the
438+ * network interface. Useful for multihomed hosts.
439+ * @param inf the InetAddress
440+ * @exception SocketException if there is an error in
441+ * the underlying protocol, such as a TCP error.
442+ * @see #getInterface()
443+ */
444+ public void setInterface(InetAddress inf) throws SocketException {
445+ if (isClosed()) {
446+ throw new SocketException("Socket is closed");
447+ }
448+ checkAddress(inf, "setInterface");
449+ synchronized (infLock) {
450+ getImpl().setOption(SocketOptions.IP_MULTICAST_IF, inf);
451+ infAddress = inf;
452+ }
453+ }
454+
455+ /**
456+ * Retrieve the address of the network interface used for
457+ * multicast packets.
458+ *
459+ * @return An <code>InetAddress</code> representing
460+ * the address of the network interface used for
461+ * multicast packets.
462+ *
463+ * @exception SocketException if there is an error in
464+ * the underlying protocol, such as a TCP error.
465+ *
466+ * @see #setInterface(java.net.InetAddress)
467+ */
468+ public InetAddress getInterface() throws SocketException {
469+ if (isClosed()) {
470+ throw new SocketException("Socket is closed");
471+ }
472+ synchronized (infLock) {
473+ InetAddress ia =
474+ (InetAddress)getImpl().getOption(SocketOptions.IP_MULTICAST_IF);
475+
476+ /**
477+ * No previous setInterface or interface can be
478+ * set using setNetworkInterface
479+ */
480+ if (infAddress == null) {
481+ return ia;
482+ }
483+
484+ /**
485+ * Same interface set with setInterface?
486+ */
487+ if (ia.equals(infAddress)) {
488+ return ia;
489+ }
490+
491+ /**
492+ * Different InetAddress from what we set with setInterface
493+ * so enumerate the current interface to see if the
494+ * address set by setInterface is bound to this interface.
495+ */
496+ try {
497+ NetworkInterface ni = NetworkInterface.getByInetAddress(ia);
498+ Enumeration addrs = ni.getInetAddresses();
499+ while (addrs.hasMoreElements()) {
500+ InetAddress addr = (InetAddress)(addrs.nextElement());
501+ if (addr.equals(infAddress)) {
502+ return infAddress;
503+ }
504+ }
505+
506+ /**
507+ * No match so reset infAddress to indicate that the
508+ * interface has changed via means
509+ */
510+ infAddress = null;
511+ return ia;
512+ } catch (Exception e) {
513+ return ia;
514+ }
515+ }
516+ }
517+
518+ /**
519+ * Specify the network interface for outgoing multicast datagrams
520+ * sent on this socket.
521+ *
522+ * @param netIf the interface
523+ * @exception SocketException if there is an error in
524+ * the underlying protocol, such as a TCP error.
525+ * @see #getNetworkInterface()
526+ * @since 1.4
527+ */
528+ public void setNetworkInterface(NetworkInterface netIf)
529+ throws SocketException {
530+
531+ synchronized (infLock) {
532+ getImpl().setOption(SocketOptions.IP_MULTICAST_IF2, netIf);
533+ infAddress = null;
534+ }
535+ }
536+
537+ /**
538+ * Get the multicast network interface set.
539+ *
540+ * @exception SocketException if there is an error in
541+ * the underlying protocol, such as a TCP error.
542+ * @return the multicast <code>NetworkInterface</code> currently set
543+ * @see #setNetworkInterface(NetworkInterface)
544+ * @since 1.4
545+ */
546+ public NetworkInterface getNetworkInterface() throws SocketException {
547+ NetworkInterface ni
548+ = (NetworkInterface)getImpl().getOption(SocketOptions.IP_MULTICAST_IF2);
549+ if (ni.getIndex() == 0) {
550+ InetAddress[] addrs = new InetAddress[1];
551+ addrs[0] = InetAddress.anyLocalAddress();
552+ return new NetworkInterface(addrs[0].getHostName(), 0, addrs);
553+ } else {
554+ return ni;
555+ }
556+ }
557+
558+ /**
559+ * Disable/Enable local loopback of multicast datagrams
560+ * The option is used by the platform's networking code as a hint
561+ * for setting whether multicast data will be looped back to
562+ * the local socket.
563+ *
564+ * <p>Because this option is a hint, applications that want to
565+ * verify what loopback mode is set to should call
566+ * {@link #getLoopbackMode()}
567+ * @param disable <code>true</code> to disable the LoopbackMode
568+ * @throws SocketException if an error occurs while setting the value
569+ * @since 1.4
570+ * @see #getLoopbackMode
571+ */
572+ public void setLoopbackMode(boolean disable) throws SocketException {
573+ getImpl().setOption(SocketOptions.IP_MULTICAST_LOOP, Boolean.valueOf(disable));
574+ }
575+
576+ /**
577+ * Get the setting for local loopback of multicast datagrams.
578+ *
579+ * @throws SocketException if an error occurs while getting the value
580+ * @return true if the LoopbackMode has been disabled
581+ * @since 1.4
582+ * @see #setLoopbackMode
583+ */
584+ public boolean getLoopbackMode() throws SocketException {
585+ return ((Boolean)getImpl().getOption(SocketOptions.IP_MULTICAST_LOOP)).booleanValue();
586+ }
587+
588+ /**
589+ * Sends a datagram packet to the destination, with a TTL (time-
590+ * to-live) other than the default for the socket. This method
591+ * need only be used in instances where a particular TTL is desired;
592+ * otherwise it is preferable to set a TTL once on the socket, and
593+ * use that default TTL for all packets. This method does <B>not
594+ * </B> alter the default TTL for the socket. Its behavior may be
595+ * affected by <code>setInterface</code>.
596+ *
597+ * <p>If there is a security manager, this method first performs some
598+ * security checks. First, if <code>p.getAddress().isMulticastAddress()</code>
599+ * is true, this method calls the
600+ * security manager's <code>checkMulticast</code> method
601+ * with <code>p.getAddress()</code> and <code>ttl</code> as its arguments.
602+ * If the evaluation of that expression is false,
603+ * this method instead calls the security manager's
604+ * <code>checkConnect</code> method with arguments
605+ * <code>p.getAddress().getHostAddress()</code> and
606+ * <code>p.getPort()</code>. Each call to a security manager method
607+ * could result in a SecurityException if the operation is not allowed.
608+ *
609+ * @param p is the packet to be sent. The packet should contain
610+ * the destination multicast ip address and the data to be sent.
611+ * One does not need to be the member of the group to send
612+ * packets to a destination multicast address.
613+ * @param ttl optional time to live for multicast packet.
614+ * default ttl is 1.
615+ *
616+ * @exception IOException is raised if an error occurs i.e
617+ * error while setting ttl.
618+ * @exception SecurityException if a security manager exists and its
619+ * <code>checkMulticast</code> or <code>checkConnect</code>
620+ * method doesn't allow the send.
621+ *
622+ * @deprecated Use the following code or its equivalent instead:
623+ * ......
624+ * int ttl = mcastSocket.getTimeToLive();
625+ * mcastSocket.setTimeToLive(newttl);
626+ * mcastSocket.send(p);
627+ * mcastSocket.setTimeToLive(ttl);
628+ * ......
629+ *
630+ * @see DatagramSocket#send
631+ * @see DatagramSocket#receive
632+ * @see SecurityManager#checkMulticast(java.net.InetAddress, byte)
633+ * @see SecurityManager#checkConnect
634+ */
635+ @Deprecated
636+ public void send(DatagramPacket p, byte ttl)
637+ throws IOException {
638+ if (isClosed())
639+ throw new SocketException("Socket is closed");
640+ checkAddress(p.getAddress(), "send");
641+ synchronized(ttlLock) {
642+ synchronized(p) {
643+ if (connectState == ST_NOT_CONNECTED) {
644+ // Security manager makes sure that the multicast address
645+ // is allowed one and that the ttl used is less
646+ // than the allowed maxttl.
647+ SecurityManager security = System.getSecurityManager();
648+ if (security != null) {
649+ if (p.getAddress().isMulticastAddress()) {
650+ security.checkMulticast(p.getAddress(), ttl);
651+ } else {
652+ security.checkConnect(p.getAddress().getHostAddress(),
653+ p.getPort());
654+ }
655+ }
656+ } else {
657+ // we're connected
658+ InetAddress packetAddress = null;
659+ packetAddress = p.getAddress();
660+ if (packetAddress == null) {
661+ p.setAddress(connectedAddress);
662+ p.setPort(connectedPort);
663+ } else if ((!packetAddress.equals(connectedAddress)) ||
664+ p.getPort() != connectedPort) {
665+ throw new SecurityException("connected address and packet address" +
666+ " differ");
667+ }
668+ }
669+ byte dttl = getTTL();
670+ try {
671+ if (ttl != dttl) {
672+ // set the ttl
673+ getImpl().setTTL(ttl);
674+ }
675+ // call the datagram method to send
676+ getImpl().send(p);
677+ } finally {
678+ // set it back to default
679+ if (ttl != dttl) {
680+ getImpl().setTTL(dttl);
681+ }
682+ }
683+ } // synch p
684+ } //synch ttl
685+ } //method
686+}