KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > net > PlainDatagramSocketImpl


1 /*
2  * @(#)PlainDatagramSocketImpl.java 1.40 05/11/17
3  *
4  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.net;
9
10 import java.io.FileDescriptor JavaDoc;
11 import java.io.IOException JavaDoc;
12 import java.io.InterruptedIOException JavaDoc;
13 import java.util.Enumeration JavaDoc;
14
15 /**
16  * Concrete datagram and multicast socket implementation base class.
17  * Note: This is not a public class, so that applets cannot call
18  * into the implementation directly and hence cannot bypass the
19  * security checks present in the DatagramSocket and MulticastSocket
20  * classes.
21  *
22  * @author Pavani Diwanji
23  */

24
25 class PlainDatagramSocketImpl extends DatagramSocketImpl JavaDoc
26 {
27     /* timeout value for receive() */
28     private int timeout = 0;
29     private int trafficClass = 0;
30     private boolean connected = false;
31     private InetAddress JavaDoc connectedAddress = null;
32     private int connectedPort = -1;
33
34     /* cached socket options */
35     private int multicastInterface = 0;
36     private boolean loopbackMode = true;
37     private int ttl = -1;
38
39     /* Used for IPv6 on Windows only */
40     private FileDescriptor JavaDoc fd1;
41     private int fduse=-1; /* saved between peek() and receive() calls */
42
43     /* saved between successive calls to receive, if data is detected
44      * on both sockets at same time. To ensure that one socket is not
45      * starved, they rotate using this field
46      */

47     private int lastfd=-1;
48
49     /*
50      * Needed for ipv6 on windows because we need to know
51      * if the socket was bound to ::0 or 0.0.0.0, when a caller
52      * asks for it. In this case, both sockets are used, but we
53      * don't know whether the caller requested ::0 or 0.0.0.0
54      * and need to remember it here.
55      */

56     private InetAddress JavaDoc anyLocalBoundAddr=null;
57
58     /**
59      * Load net library into runtime.
60      */

61     static {
62     java.security.AccessController.doPrivileged(
63           new sun.security.action.LoadLibraryAction("net"));
64     init();
65     }
66
67     /**
68      * Creates a datagram socket
69      */

70     protected synchronized void create() throws SocketException JavaDoc {
71     fd = new FileDescriptor JavaDoc();
72     fd1 = new FileDescriptor JavaDoc();
73     datagramSocketCreate();
74     }
75
76     /**
77      * Binds a datagram socket to a local port.
78      */

79     protected synchronized void bind(int lport, InetAddress JavaDoc laddr)
80         throws SocketException JavaDoc {
81     
82     bind0(lport, laddr);
83     if (laddr.isAnyLocalAddress()) {
84         anyLocalBoundAddr = laddr;
85     }
86     }
87
88     protected synchronized native void bind0(int lport, InetAddress JavaDoc laddr)
89         throws SocketException JavaDoc;
90
91     /**
92      * Sends a datagram packet. The packet contains the data and the
93      * destination address to send the packet to.
94      * @param packet to be sent.
95      */

96     protected native void send(DatagramPacket JavaDoc p) throws IOException JavaDoc;
97
98     /**
99      * Connects a datagram socket to a remote destination. This associates the remote
100      * address with the local socket so that datagrams may only be sent to this destination
101      * and received from this destination.
102      * @param address the remote InetAddress to connect to
103      * @param port the remote port number
104      */

105     protected void connect(InetAddress JavaDoc address, int port) throws SocketException JavaDoc {
106     connect0(address, port);
107     connectedAddress = address;
108     connectedPort = port;
109     connected = true;
110     }
111
112     /**
113      * Disconnects a previously connected socket. Does nothing if the socket was
114      * not connected already.
115      */

116     protected void disconnect() {
117     disconnect0(connectedAddress.family);
118     connected = false;
119     connectedAddress = null;
120     connectedPort = -1;
121     }
122
123     /**
124      * Peek at the packet to see who it is from.
125      * @param return the address which the packet came from.
126      */

127     protected synchronized native int peek(InetAddress JavaDoc i) throws IOException JavaDoc;
128     protected synchronized native int peekData(DatagramPacket JavaDoc p) throws IOException JavaDoc;
129     /**
130      * Receive the datagram packet.
131      * @param Packet Received.
132      */

133     protected synchronized void receive(DatagramPacket JavaDoc p)
134         throws IOException JavaDoc {
135     try {
136         receive0(p);
137     } finally {
138         fduse = -1;
139     }
140     }
141
142     protected synchronized native void receive0(DatagramPacket JavaDoc p)
143         throws IOException JavaDoc;
144
145     /**
146      * Set the TTL (time-to-live) option.
147      * @param TTL to be set.
148      */

149     protected native void setTimeToLive(int ttl) throws IOException JavaDoc;
150
151     /**
152      * Get the TTL (time-to-live) option.
153      */

154     protected native int getTimeToLive() throws IOException JavaDoc;
155
156     /**
157      * Set the TTL (time-to-live) option.
158      * @param TTL to be set.
159      */

160     protected native void setTTL(byte ttl) throws IOException JavaDoc;
161
162     /**
163      * Get the TTL (time-to-live) option.
164      */

165     protected native byte getTTL() throws IOException JavaDoc;
166
167     /**
168      * Join the multicast group.
169      * @param multicast address to join.
170      */

171     protected void join(InetAddress JavaDoc inetaddr) throws IOException JavaDoc {
172     join(inetaddr, null);
173     }
174
175     /**
176      * Leave the multicast group.
177      * @param multicast address to leave.
178      */

179     protected void leave(InetAddress JavaDoc inetaddr) throws IOException JavaDoc {
180     leave(inetaddr, null);
181     }
182     /**
183      * Join the multicast group.
184      * @param multicast address to join.
185      * @param netIf specifies the local interface to receive multicast
186      * datagram packets
187      * @throws IllegalArgumentException if mcastaddr is null or is a
188      * SocketAddress subclass not supported by this socket
189      * @since 1.4
190      */

191
192     protected void joinGroup(SocketAddress JavaDoc mcastaddr, NetworkInterface JavaDoc netIf)
193     throws IOException JavaDoc {
194     if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress JavaDoc))
195         throw new IllegalArgumentException JavaDoc("Unsupported address type");
196     join(((InetSocketAddress JavaDoc)mcastaddr).getAddress(), netIf);
197     }
198
199     private native void join(InetAddress JavaDoc inetaddr, NetworkInterface JavaDoc netIf)
200     throws IOException JavaDoc;
201
202     /**
203      * Leave the multicast group.
204      * @param multicast address to leave.
205      * @param netIf specified the local interface to leave the group at
206      * @throws IllegalArgumentException if mcastaddr is null or is a
207      * SocketAddress subclass not supported by this socket
208      * @since 1.4
209      */

210     protected void leaveGroup(SocketAddress JavaDoc mcastaddr, NetworkInterface JavaDoc netIf)
211     throws IOException JavaDoc {
212     if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress JavaDoc))
213         throw new IllegalArgumentException JavaDoc("Unsupported address type");
214     leave(((InetSocketAddress JavaDoc)mcastaddr).getAddress(), netIf);
215     }
216
217     private native void leave(InetAddress JavaDoc inetaddr, NetworkInterface JavaDoc netIf)
218     throws IOException JavaDoc;
219
220     /**
221      * Close the socket.
222      */

223     protected void close() {
224     if (fd != null || fd1 != null) {
225         datagramSocketClose();
226         fd = null;
227         fd1 = null;
228     }
229     }
230
231     protected void finalize() {
232     close();
233     }
234
235     /**
236      * set a value - since we only support (setting) binary options
237      * here, o must be a Boolean
238      */

239
240      public void setOption(int optID, Object JavaDoc o) throws SocketException JavaDoc {
241          if (fd == null && fd1 == null) {
242             throw new SocketException JavaDoc("Socket Closed");
243          }
244      switch (optID) {
245         /* check type safety b4 going native. These should never
246          * fail, since only java.Socket* has access to
247          * PlainSocketImpl.setOption().
248          */

249      case SO_TIMEOUT:
250          if (o == null || !(o instanceof Integer JavaDoc)) {
251          throw new SocketException JavaDoc("bad argument for SO_TIMEOUT");
252          }
253          int tmp = ((Integer JavaDoc) o).intValue();
254          if (tmp < 0)
255          throw new IllegalArgumentException JavaDoc("timeout < 0");
256          timeout = tmp;
257          return;
258      case IP_TOS:
259          if (o == null || !(o instanceof Integer JavaDoc)) {
260          throw new SocketException JavaDoc("bad argument for IP_TOS");
261          }
262          trafficClass = ((Integer JavaDoc)o).intValue();
263          break;
264      case SO_REUSEADDR:
265          if (o == null || !(o instanceof Boolean JavaDoc)) {
266          throw new SocketException JavaDoc("bad argument for SO_REUSEADDR");
267          }
268          break;
269      case SO_BROADCAST:
270          if (o == null || !(o instanceof Boolean JavaDoc)) {
271          throw new SocketException JavaDoc("bad argument for SO_BROADCAST");
272          }
273          break;
274      case SO_BINDADDR:
275          throw new SocketException JavaDoc("Cannot re-bind Socket");
276      case SO_RCVBUF:
277      case SO_SNDBUF:
278          if (o == null || !(o instanceof Integer JavaDoc) ||
279          ((Integer JavaDoc)o).intValue() < 0) {
280          throw new SocketException JavaDoc("bad argument for SO_SNDBUF or " +
281                        "SO_RCVBUF");
282          }
283          break;
284      case IP_MULTICAST_IF:
285          if (o == null || !(o instanceof InetAddress JavaDoc))
286          throw new SocketException JavaDoc("bad argument for IP_MULTICAST_IF");
287          break;
288      case IP_MULTICAST_IF2:
289          if (o == null || !(o instanceof NetworkInterface JavaDoc))
290          throw new SocketException JavaDoc("bad argument for IP_MULTICAST_IF2");
291          break;
292      case IP_MULTICAST_LOOP:
293          if (o == null || !(o instanceof Boolean JavaDoc))
294          throw new SocketException JavaDoc("bad argument for IP_MULTICAST_LOOP");
295          break;
296      default:
297          throw new SocketException JavaDoc("invalid option: " + optID);
298      }
299      socketSetOption(optID, o);
300      }
301
302     /*
303      * get option's state - set or not
304      */

305
306     public Object JavaDoc getOption(int optID) throws SocketException JavaDoc {
307         if (fd == null && fd1 == null) {
308             throw new SocketException JavaDoc("Socket Closed");
309         }
310
311     Object JavaDoc result;
312
313     switch (optID) {
314         case SO_TIMEOUT:
315         result = new Integer JavaDoc(timeout);
316         break;
317     
318         case IP_TOS:
319         result = socketGetOption(optID);
320         if ( ((Integer JavaDoc)result).intValue() == -1) {
321             result = new Integer JavaDoc(trafficClass);
322         }
323         break;
324
325         case SO_BINDADDR:
326         if (fd != null && fd1 != null) {
327             return anyLocalBoundAddr;
328         }
329         /* fall through */
330         case IP_MULTICAST_IF:
331         case IP_MULTICAST_IF2:
332         case SO_RCVBUF:
333         case SO_SNDBUF:
334         case IP_MULTICAST_LOOP:
335         case SO_REUSEADDR:
336         case SO_BROADCAST:
337         result = socketGetOption(optID);
338         break;
339
340         default:
341         throw new SocketException JavaDoc("invalid option: " + optID);
342     }
343
344     return result;
345     }
346
347     private native void datagramSocketCreate() throws SocketException JavaDoc;
348     private native void datagramSocketClose();
349     private native void socketSetOption(int opt, Object JavaDoc val)
350         throws SocketException JavaDoc;
351     private native Object JavaDoc socketGetOption(int opt) throws SocketException JavaDoc;
352
353     private native void connect0(InetAddress JavaDoc address, int port) throws SocketException JavaDoc;
354     private native void disconnect0(int family);
355
356     /**
357      * Perform class load-time initializations.
358      */

359     private native static void init();
360
361 }
362
363
Popular Tags