1 /* PlainDatagramSocketImpl.java -- Default DatagramSocket implementation
2 Copyright (C) 1998, 1999, 2001, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
41 import gnu.java.nio.VMChannel;
43 import java.io.IOException;
44 import java.io.InterruptedIOException;
45 import java.net.DatagramPacket;
46 import java.net.DatagramSocketImpl;
47 import java.net.InetAddress;
48 import java.net.InetSocketAddress;
49 import java.net.NetworkInterface;
50 import java.net.SocketAddress;
51 import java.net.SocketException;
52 import java.net.SocketTimeoutException;
53 import java.nio.ByteBuffer;
56 * Written using on-line Java Platform 1.2 API Specification, as well
57 * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
58 * Status: Believed complete and correct.
62 * This is the default socket implementation for datagram sockets.
63 * It makes native calls to C routines that implement BSD style
64 * SOCK_DGRAM sockets in the AF_INET family.
66 * @author Aaron M. Renn (arenn@urbanophile.com)
67 * @author Warren Levy (warrenl@cygnus.com)
69 public final class PlainDatagramSocketImpl extends DatagramSocketImpl
71 private final VMChannel channel;
74 * The platform-specific socket implementation.
76 private final VMPlainSocketImpl impl;
79 * Lock object to serialize threads wanting to receive
81 private final Object RECEIVE_LOCK = new Object();
84 * Lock object to serialize threads wanting to send
86 private final Object SEND_LOCK = new Object();
89 * Default do nothing constructor
91 public PlainDatagramSocketImpl() throws IOException
93 channel = new VMChannel();
94 impl = new VMPlainSocketImpl(channel);
97 /*protected void finalize() throws Throwable
101 if (channel.getState().isValid())
107 /*public int getNativeFD()
113 * Binds this socket to a particular port and interface
115 * @param port The port to bind to
116 * @param addr The address to bind to
118 * @exception SocketException If an error occurs
120 protected synchronized void bind(int port, InetAddress addr)
121 throws SocketException
125 impl.bind(new InetSocketAddress(addr, port));
127 catch (SocketException se)
131 catch (IOException ioe)
133 SocketException se = new SocketException();
140 * Creates a new datagram socket
142 * @exception SocketException If an error occurs
144 protected synchronized void create() throws SocketException
148 channel.initSocket(false);
150 catch (SocketException se)
154 catch (IOException ioe)
156 SocketException se = new SocketException();
163 * Connects to the remote address and port specified as arguments.
165 * @param addr The remote address to connect to
166 * @param port The remote port to connect to
168 * @exception SocketException If an error occurs
170 protected void connect(InetAddress addr, int port) throws SocketException
172 channel.connect(new InetSocketAddress(addr, port), 0);
176 * Disconnects the socket.
180 protected void disconnect()
186 if (channel.getState().isValid())
187 channel.disconnect();
189 catch (IOException ioe)
196 * Sets the Time to Live value for the socket
198 * @param ttl The new TTL value
200 * @exception IOException If an error occurs
202 protected synchronized void setTimeToLive(int ttl) throws IOException
204 impl.setTimeToLive(ttl);
208 * Gets the Time to Live value for the socket
210 * @return The TTL value
212 * @exception IOException If an error occurs
214 protected synchronized int getTimeToLive() throws IOException
216 return impl.getTimeToLive();
219 protected int getLocalPort()
226 InetSocketAddress local = channel.getLocalAddress();
229 return local.getPort();
231 catch (IOException ioe)
238 * Sends a packet of data to a remote host
240 * @param packet The packet to send
242 * @exception IOException If an error occurs
244 protected void send(DatagramPacket packet) throws IOException
246 synchronized (SEND_LOCK)
248 ByteBuffer buf = ByteBuffer.wrap(packet.getData(),
251 InetAddress remote = packet.getAddress();
252 int port = packet.getPort();
254 throw new NullPointerException();
256 throw new SocketException("invalid port " + port);
261 channel.send(buf, new InetSocketAddress(remote, port));
264 catch (InterruptedIOException ioe)
266 // Ignore; interrupted system call.
273 * Receives a UDP packet from the network
275 * @param packet The packet to fill in with the data received
277 * @exception IOException IOException If an error occurs
279 protected void receive(DatagramPacket packet)
282 synchronized(RECEIVE_LOCK)
284 ByteBuffer buf = ByteBuffer.wrap(packet.getData(),
287 SocketAddress addr = null;
292 addr = channel.receive(buf);
295 catch (SocketTimeoutException ste)
299 catch (InterruptedIOException iioe)
305 packet.setSocketAddress(addr);
306 packet.setLength(buf.position() - packet.getOffset());
312 * Sets the value of an option on the socket
314 * @param optionId The identifier of the option to set
315 * @param value The value of the option to set
317 * @exception SocketException If an error occurs
319 public synchronized void setOption(int optionId, Object value)
320 throws SocketException
324 case IP_MULTICAST_IF:
325 case IP_MULTICAST_IF2:
326 impl.setMulticastInterface(optionId, (InetAddress) value);
329 case IP_MULTICAST_LOOP:
340 impl.setOption(optionId, value);
344 throw new SocketException("cannot set option " + optionId);
349 * Retrieves the value of an option on the socket
351 * @param optionId The identifier of the option to retrieve
353 * @return The value of the option
355 * @exception SocketException If an error occurs
357 public synchronized Object getOption(int optionId)
358 throws SocketException
360 if (optionId == SO_BINDADDR)
364 InetSocketAddress local = channel.getLocalAddress();
367 return local.getAddress();
369 catch (SocketException se)
373 catch (IOException ioe)
375 SocketException se = new SocketException();
380 if (optionId == IP_MULTICAST_IF || optionId == IP_MULTICAST_IF2)
381 return impl.getMulticastInterface(optionId);
383 return impl.getOption(optionId);
389 protected synchronized void close()
393 if (channel.getState().isValid())
396 catch (IOException ioe)
402 * Gets the Time to Live value for the socket
404 * @return The TTL value
406 * @exception IOException If an error occurs
410 protected synchronized byte getTTL() throws IOException
412 return (byte) getTimeToLive();
416 * Sets the Time to Live value for the socket
418 * @param ttl The new TTL value
420 * @exception IOException If an error occurs
424 protected synchronized void setTTL(byte ttl) throws IOException
426 setTimeToLive(((int) ttl) & 0xFF);
430 * Joins a multicast group
432 * @param addr The group to join
434 * @exception IOException If an error occurs
436 protected synchronized void join(InetAddress addr) throws IOException
442 * Leaves a multicast group
444 * @param addr The group to leave
446 * @exception IOException If an error occurs
448 protected synchronized void leave(InetAddress addr) throws IOException
454 * What does this method really do?
456 protected synchronized int peek(InetAddress addr) throws IOException
458 throw new IOException("Not Implemented Yet");
461 public int peekData(DatagramPacket packet)
463 throw new InternalError
464 ("PlainDatagramSocketImpl::peekData is not implemented");
467 public void joinGroup(SocketAddress address, NetworkInterface netIf)
471 throw new NullPointerException();
472 if (!(address instanceof InetSocketAddress))
473 throw new SocketException("unknown address type");
474 impl.joinGroup((InetSocketAddress) address, netIf);
477 public void leaveGroup(SocketAddress address, NetworkInterface netIf)
481 throw new NullPointerException();
482 if (!(address instanceof InetSocketAddress))
483 throw new SocketException("unknown address type");
484 impl.leaveGroup((InetSocketAddress) address, netIf);