summaryrefslogtreecommitdiff
path: root/libjava/java/net/DatagramSocket.java
diff options
context:
space:
mode:
authorTom Tromey <tromey@gcc.gnu.org>2007-01-09 19:58:05 +0000
committerTom Tromey <tromey@gcc.gnu.org>2007-01-09 19:58:05 +0000
commit97b8365cafc3a344a22d3980b8ed885f5c6d8357 (patch)
tree996a5f57d4a68c53473382e45cb22f574cb3e4db /libjava/java/net/DatagramSocket.java
parentc648dedbde727ca3f883bb5fd773aa4af70d3369 (diff)
Merged gcj-eclipse branch to trunk.
From-SVN: r120621
Diffstat (limited to 'libjava/java/net/DatagramSocket.java')
-rw-r--r--libjava/java/net/DatagramSocket.java939
1 files changed, 939 insertions, 0 deletions
diff --git a/libjava/java/net/DatagramSocket.java b/libjava/java/net/DatagramSocket.java
new file mode 100644
index 00000000000..d8837c006b5
--- /dev/null
+++ b/libjava/java/net/DatagramSocket.java
@@ -0,0 +1,939 @@
+/* DatagramSocket.java -- A class to model UDP sockets
+ Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.net;
+
+import gnu.classpath.SystemProperties;
+
+import gnu.java.net.PlainDatagramSocketImpl;
+import gnu.java.nio.DatagramChannelImpl;
+
+import java.io.IOException;
+import java.nio.channels.DatagramChannel;
+import java.nio.channels.IllegalBlockingModeException;
+
+
+/**
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status: Believed complete and correct.
+ */
+/**
+ * This class models a connectionless datagram socket that sends
+ * individual packets of data across the network. In the TCP/IP world,
+ * this means UDP. Datagram packets do not have guaranteed delivery,
+ * or any guarantee about the order the data will be received on the
+ * remote host.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Warren Levy (warrenl@cygnus.com)
+ * @date May 3, 1999.
+ */
+public class DatagramSocket
+{
+ /**
+ * This is the user DatagramSocketImplFactory for this class. If this
+ * variable is null, a default factory is used.
+ */
+ private static DatagramSocketImplFactory factory;
+
+ /**
+ * This is the implementation object used by this socket.
+ */
+ private DatagramSocketImpl impl;
+
+ /**
+ * True if socket implementation was created.
+ */
+ private boolean implCreated;
+
+ /**
+ * This is the address we are "connected" to
+ */
+ private InetAddress remoteAddress;
+
+ /**
+ * This is the port we are "connected" to
+ */
+ private int remotePort = -1;
+
+ /**
+ * True if socket is bound.
+ */
+ private boolean bound;
+
+ /**
+ * Creates a <code>DatagramSocket</code> from a specified
+ * <code>DatagramSocketImpl</code> instance
+ *
+ * @param impl The <code>DatagramSocketImpl</code> the socket will be
+ * created from
+ *
+ * @since 1.4
+ */
+ protected DatagramSocket(DatagramSocketImpl impl)
+ {
+ if (impl == null)
+ throw new NullPointerException("impl may not be null");
+
+ this.impl = impl;
+ this.remoteAddress = null;
+ this.remotePort = -1;
+ }
+
+ /**
+ * Initializes a new instance of <code>DatagramSocket</code> that binds to
+ * a random port and every address on the local machine.
+ *
+ * @exception SocketException If an error occurs.
+ * @exception SecurityException If a security manager exists and
+ * its <code>checkListen</code> method doesn't allow the operation.
+ */
+ public DatagramSocket() throws SocketException
+ {
+ this(new InetSocketAddress(0));
+ }
+
+ /**
+ * Initializes a new instance of <code>DatagramSocket</code> that binds to
+ * the specified port and every address on the local machine.
+ *
+ * @param port The local port number to bind to.
+ *
+ * @exception SecurityException If a security manager exists and its
+ * <code>checkListen</code> method doesn't allow the operation.
+ * @exception SocketException If an error occurs.
+ */
+ public DatagramSocket(int port) throws SocketException
+ {
+ this(new InetSocketAddress(port));
+ }
+
+ /**
+ * Initializes a new instance of <code>DatagramSocket</code> that binds to
+ * the specified local port and address.
+ *
+ * @param port The local port number to bind to.
+ * @param addr The local address to bind to.
+ *
+ * @exception SecurityException If a security manager exists and its
+ * checkListen method doesn't allow the operation.
+ * @exception SocketException If an error occurs.
+ */
+ public DatagramSocket(int port, InetAddress addr) throws SocketException
+ {
+ this(new InetSocketAddress(addr, port));
+ }
+
+ /**
+ * Initializes a new instance of <code>DatagramSocket</code> that binds to
+ * the specified local port and address.
+ *
+ * @param address The local address and port number to bind to.
+ *
+ * @exception SecurityException If a security manager exists and its
+ * <code>checkListen</code> method doesn't allow the operation.
+ * @exception SocketException If an error occurs.
+ *
+ * @since 1.4
+ */
+ public DatagramSocket(SocketAddress address) throws SocketException
+ {
+ String propVal = SystemProperties.getProperty("impl.prefix");
+ if (propVal == null || propVal.equals(""))
+ {
+ if (factory != null)
+ impl = factory.createDatagramSocketImpl();
+ else
+ impl = new PlainDatagramSocketImpl();
+ }
+ else
+ try
+ {
+ impl =
+ (DatagramSocketImpl) Class.forName("java.net." + propVal
+ + "DatagramSocketImpl")
+ .newInstance();
+ }
+ catch (Exception e)
+ {
+ System.err.println("Could not instantiate class: java.net."
+ + propVal + "DatagramSocketImpl");
+ impl = new PlainDatagramSocketImpl();
+ }
+
+ if (address != null)
+ bind(address);
+ }
+
+ // This needs to be accessible from java.net.MulticastSocket
+ DatagramSocketImpl getImpl() throws SocketException
+ {
+ try
+ {
+ if (! implCreated)
+ {
+ impl.create();
+ implCreated = true;
+ }
+
+ return impl;
+ }
+ catch (IOException e)
+ {
+ SocketException se = new SocketException();
+ se.initCause(e);
+ throw se;
+ }
+ }
+
+ /**
+ * Closes this datagram socket.
+ */
+ public void close()
+ {
+ if (isClosed())
+ return;
+
+ try
+ {
+ getImpl().close();
+ }
+ catch (SocketException e)
+ {
+ // Ignore this case, just close the socket in finally clause.
+ }
+ finally
+ {
+ remoteAddress = null;
+ remotePort = -1;
+ impl = null;
+ }
+
+ try
+ {
+ if (getChannel() != null)
+ getChannel().close();
+ }
+ catch (IOException e)
+ {
+ // Do nothing.
+ }
+ }
+
+ /**
+ * This method returns the remote address to which this socket is
+ * connected. If this socket is not connected, then this method will
+ * return <code>null</code>.
+ *
+ * @return The remote address.
+ *
+ * @since 1.2
+ */
+ public InetAddress getInetAddress()
+ {
+ return remoteAddress;
+ }
+
+ /**
+ * This method returns the remote port to which this socket is
+ * connected. If this socket is not connected, then this method will
+ * return -1.
+ *
+ * @return The remote port.
+ *
+ * @since 1.2
+ */
+ public int getPort()
+ {
+ return remotePort;
+ }
+
+ /**
+ * Returns the local address this datagram socket is bound to.
+ *
+ * @return The local address is the socket is bound or null
+ *
+ * @since 1.1
+ */
+ public InetAddress getLocalAddress()
+ {
+ if (! isBound())
+ return null;
+
+ InetAddress localAddr;
+
+ try
+ {
+ localAddr =
+ (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR);
+
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkConnect(localAddr.getHostName(), -1);
+ }
+ catch (SecurityException e)
+ {
+ localAddr = InetAddress.ANY_IF;
+ }
+ catch (SocketException e)
+ {
+ // This cannot happen as we are bound.
+ return null;
+ }
+
+ return localAddr;
+ }
+
+ /**
+ * Returns the local port this socket is bound to.
+ *
+ * @return The local port number.
+ */
+ public int getLocalPort()
+ {
+ if (isClosed())
+ return -1;
+
+ try
+ {
+ return getImpl().getLocalPort();
+ }
+ catch (SocketException e)
+ {
+ // This cannot happen as we are bound.
+ return 0;
+ }
+ }
+
+ /**
+ * Returns the value of the socket's SO_TIMEOUT setting. If this method
+ * returns 0 then SO_TIMEOUT is disabled.
+ *
+ * @return The current timeout in milliseconds.
+ *
+ * @exception SocketException If an error occurs.
+ *
+ * @since 1.1
+ */
+ public synchronized int getSoTimeout() throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ Object buf = getImpl().getOption(SocketOptions.SO_TIMEOUT);
+
+ if (buf instanceof Integer)
+ return ((Integer) buf).intValue();
+
+ throw new SocketException("unexpected type");
+ }
+
+ /**
+ * Sets the value of the socket's SO_TIMEOUT value. A value of 0 will
+ * disable SO_TIMEOUT. Any other value is the number of milliseconds
+ * a socket read/write will block before timing out.
+ *
+ * @param timeout The new SO_TIMEOUT value in milliseconds.
+ *
+ * @exception SocketException If an error occurs.
+ *
+ * @since 1.1
+ */
+ public synchronized void setSoTimeout(int timeout) throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ if (timeout < 0)
+ throw new IllegalArgumentException("Invalid timeout: " + timeout);
+
+ getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
+ }
+
+ /**
+ * This method returns the value of the system level socket option
+ * SO_SNDBUF, which is used by the operating system to tune buffer
+ * sizes for data transfers.
+ *
+ * @return The send buffer size.
+ *
+ * @exception SocketException If an error occurs.
+ *
+ * @since 1.2
+ */
+ public int getSendBufferSize() throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ Object buf = getImpl().getOption(SocketOptions.SO_SNDBUF);
+
+ if (buf instanceof Integer)
+ return ((Integer) buf).intValue();
+
+ throw new SocketException("unexpected type");
+ }
+
+ /**
+ * This method sets the value for the system level socket option
+ * SO_SNDBUF to the specified value. Note that valid values for this
+ * option are specific to a given operating system.
+ *
+ * @param size The new send buffer size.
+ *
+ * @exception SocketException If an error occurs.
+ * @exception IllegalArgumentException If size is 0 or negative.
+ *
+ * @since 1.2
+ */
+ public void setSendBufferSize(int size) throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ if (size < 0)
+ throw new IllegalArgumentException("Buffer size is less than 0");
+
+ getImpl().setOption(SocketOptions.SO_SNDBUF, new Integer(size));
+ }
+
+ /**
+ * This method returns the value of the system level socket option
+ * SO_RCVBUF, which is used by the operating system to tune buffer
+ * sizes for data transfers.
+ *
+ * @return The receive buffer size.
+ *
+ * @exception SocketException If an error occurs.
+ *
+ * @since 1.2
+ */
+ public int getReceiveBufferSize() throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ Object buf = getImpl().getOption(SocketOptions.SO_RCVBUF);
+
+ if (buf instanceof Integer)
+ return ((Integer) buf).intValue();
+
+ throw new SocketException("unexpected type");
+ }
+
+ /**
+ * This method sets the value for the system level socket option
+ * SO_RCVBUF to the specified value. Note that valid values for this
+ * option are specific to a given operating system.
+ *
+ * @param size The new receive buffer size.
+ *
+ * @exception SocketException If an error occurs.
+ * @exception IllegalArgumentException If size is 0 or negative.
+ *
+ * @since 1.2
+ */
+ public void setReceiveBufferSize(int size) throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ if (size < 0)
+ throw new IllegalArgumentException("Buffer size is less than 0");
+
+ getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer(size));
+ }
+
+ /**
+ * This method connects this socket to the specified address and port.
+ * When a datagram socket is connected, it will only send or receive
+ * packets to and from the host to which it is connected. A multicast
+ * socket that is connected may only send and not receive packets.
+ *
+ * @param address The address to connect this socket to.
+ * @param port The port to connect this socket to.
+ *
+ * @exception IllegalArgumentException If address or port are invalid.
+ * @exception SecurityException If the caller is not allowed to send
+ * datagrams to or receive from this address and port.
+ *
+ * @since 1.2
+ */
+ public void connect(InetAddress address, int port)
+ {
+ if (address == null)
+ throw new IllegalArgumentException("Connect address may not be null");
+
+ if ((port < 1) || (port > 65535))
+ throw new IllegalArgumentException("Port number is illegal: " + port);
+
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkConnect(address.getHostName(), port);
+
+ try
+ {
+ getImpl().connect(address, port);
+ remoteAddress = address;
+ remotePort = port;
+ }
+ catch (SocketException e)
+ {
+ // This means simply not connected or connect not implemented.
+ }
+ }
+
+ /**
+ * This method disconnects this socket from the address/port it was
+ * connected to. If the socket was not connected in the first place,
+ * this method does nothing.
+ *
+ * @since 1.2
+ */
+ public void disconnect()
+ {
+ if (! isConnected())
+ return;
+
+ try
+ {
+ getImpl().disconnect();
+ }
+ catch (SocketException e)
+ {
+ // This cannot happen as we are connected.
+ }
+ finally
+ {
+ remoteAddress = null;
+ remotePort = -1;
+ }
+ }
+
+ /**
+ * Reads a datagram packet from the socket. Note that this method
+ * will block until a packet is received from the network. On return,
+ * the passed in <code>DatagramPacket</code> is populated with the data
+ * received and all the other information about the packet.
+ *
+ * @param p A <code>DatagramPacket</code> for storing the data
+ *
+ * @exception IOException If an error occurs.
+ * @exception SocketTimeoutException If setSoTimeout was previously called
+ * and the timeout has expired.
+ * @exception PortUnreachableException If the socket is connected to a
+ * currently unreachable destination. Note, there is no guarantee that the
+ * exception will be thrown.
+ * @exception IllegalBlockingModeException If this socket has an associated
+ * channel, and the channel is in non-blocking mode.
+ * @exception SecurityException If a security manager exists and its
+ * checkAccept method doesn't allow the receive.
+ */
+ public synchronized void receive(DatagramPacket p) throws IOException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ if (remoteAddress != null && remoteAddress.isMulticastAddress())
+ throw new IOException
+ ("Socket connected to a multicast address my not receive");
+
+ if (getChannel() != null && ! getChannel().isBlocking()
+ && ! ((DatagramChannelImpl) getChannel()).isInChannelOperation())
+ throw new IllegalBlockingModeException();
+
+ getImpl().receive(p);
+
+ SecurityManager s = System.getSecurityManager();
+ if (s != null && isConnected())
+ s.checkAccept(p.getAddress().getHostName(), p.getPort());
+ }
+
+ /**
+ * Sends the specified packet. The host and port to which the packet
+ * are to be sent should be set inside the packet.
+ *
+ * @param p The datagram packet to send.
+ *
+ * @exception IOException If an error occurs.
+ * @exception SecurityException If a security manager exists and its
+ * checkMulticast or checkConnect method doesn't allow the send.
+ * @exception PortUnreachableException If the socket is connected to a
+ * currently unreachable destination. Note, there is no guarantee that the
+ * exception will be thrown.
+ * @exception IllegalBlockingModeException If this socket has an associated
+ * channel, and the channel is in non-blocking mode.
+ */
+ public void send(DatagramPacket p) throws IOException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ // JDK1.2: Don't do security checks if socket is connected; see jdk1.2 api.
+ SecurityManager s = System.getSecurityManager();
+ if (s != null && ! isConnected())
+ {
+ InetAddress addr = p.getAddress();
+ if (addr.isMulticastAddress())
+ s.checkMulticast(addr);
+ else
+ s.checkConnect(addr.getHostAddress(), p.getPort());
+ }
+
+ if (isConnected())
+ {
+ if (p.getAddress() != null
+ && (remoteAddress != p.getAddress() || remotePort != p.getPort()))
+ throw new IllegalArgumentException
+ ("DatagramPacket address does not match remote address");
+ }
+
+ // FIXME: if this is a subclass of MulticastSocket,
+ // use getTimeToLive for TTL val.
+ if (getChannel() != null && ! getChannel().isBlocking()
+ && ! ((DatagramChannelImpl) getChannel()).isInChannelOperation())
+ throw new IllegalBlockingModeException();
+
+ getImpl().send(p);
+ }
+
+ /**
+ * Binds the socket to the given socket address.
+ *
+ * @param address The socket address to bind to.
+ *
+ * @exception SocketException If an error occurs.
+ * @exception SecurityException If a security manager exists and
+ * its checkListen method doesn't allow the operation.
+ * @exception IllegalArgumentException If address type is not supported.
+ *
+ * @since 1.4
+ */
+ public void bind(SocketAddress address) throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ if (! (address instanceof InetSocketAddress))
+ throw new IllegalArgumentException("unsupported address type");
+
+ InetAddress addr = ((InetSocketAddress) address).getAddress();
+ int port = ((InetSocketAddress) address).getPort();
+
+ if (port < 0 || port > 65535)
+ throw new IllegalArgumentException("Invalid port: " + port);
+
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkListen(port);
+
+ if (addr == null)
+ addr = InetAddress.ANY_IF;
+
+ try
+ {
+ getImpl().bind(port, addr);
+ bound = true;
+ }
+ catch (SocketException exception)
+ {
+ getImpl().close();
+ throw exception;
+ }
+ catch (RuntimeException exception)
+ {
+ getImpl().close();
+ throw exception;
+ }
+ catch (Error error)
+ {
+ getImpl().close();
+ throw error;
+ }
+ }
+
+ /**
+ * Checks if the datagram socket is closed.
+ *
+ * @return True if socket is closed, false otherwise.
+ *
+ * @since 1.4
+ */
+ public boolean isClosed()
+ {
+ return impl == null;
+ }
+
+ /**
+ * Returns the datagram channel assoziated with this datagram socket.
+ *
+ * @return The associated <code>DatagramChannel</code> object or null
+ *
+ * @since 1.4
+ */
+ public DatagramChannel getChannel()
+ {
+ return null;
+ }
+
+ /**
+ * Connects the datagram socket to a specified socket address.
+ *
+ * @param address The socket address to connect to.
+ *
+ * @exception SocketException If an error occurs.
+ * @exception IllegalArgumentException If address type is not supported.
+ *
+ * @since 1.4
+ */
+ public void connect(SocketAddress address) throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ if (! (address instanceof InetSocketAddress))
+ throw new IllegalArgumentException("unsupported address type");
+
+ InetSocketAddress tmp = (InetSocketAddress) address;
+ connect(tmp.getAddress(), tmp.getPort());
+ }
+
+ /**
+ * Returns the binding state of the socket.
+ *
+ * @return True if socket bound, false otherwise.
+ *
+ * @since 1.4
+ */
+ public boolean isBound()
+ {
+ return bound;
+ }
+
+ /**
+ * Returns the connection state of the socket.
+ *
+ * @return True if socket is connected, false otherwise.
+ *
+ * @since 1.4
+ */
+ public boolean isConnected()
+ {
+ return remoteAddress != null;
+ }
+
+ /**
+ * Returns the SocketAddress of the host this socket is conneted to
+ * or null if this socket is not connected.
+ *
+ * @return The socket address of the remote host if connected or null
+ *
+ * @since 1.4
+ */
+ public SocketAddress getRemoteSocketAddress()
+ {
+ if (! isConnected())
+ return null;
+
+ return new InetSocketAddress(remoteAddress, remotePort);
+ }
+
+ /**
+ * Returns the local SocketAddress this socket is bound to.
+ *
+ * @return The local SocketAddress or null if the socket is not bound.
+ *
+ * @since 1.4
+ */
+ public SocketAddress getLocalSocketAddress()
+ {
+ if (! isBound())
+ return null;
+
+ return new InetSocketAddress(getLocalAddress(), getLocalPort());
+ }
+
+ /**
+ * Enables/Disables SO_REUSEADDR.
+ *
+ * @param on Whether or not to have SO_REUSEADDR turned on.
+ *
+ * @exception SocketException If an error occurs.
+ *
+ * @since 1.4
+ */
+ public void setReuseAddress(boolean on) throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
+ }
+
+ /**
+ * Checks if SO_REUSEADDR is enabled.
+ *
+ * @return True if SO_REUSEADDR is set on the socket, false otherwise.
+ *
+ * @exception SocketException If an error occurs.
+ *
+ * @since 1.4
+ */
+ public boolean getReuseAddress() throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ Object buf = getImpl().getOption(SocketOptions.SO_REUSEADDR);
+
+ if (buf instanceof Boolean)
+ return ((Boolean) buf).booleanValue();
+
+ throw new SocketException("unexpected type");
+ }
+
+ /**
+ * Enables/Disables SO_BROADCAST
+ *
+ * @param enable True if SO_BROADCAST should be enabled, false otherwise.
+ *
+ * @exception SocketException If an error occurs
+ *
+ * @since 1.4
+ */
+ public void setBroadcast(boolean enable) throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ getImpl().setOption(SocketOptions.SO_BROADCAST, Boolean.valueOf(enable));
+ }
+
+ /**
+ * Checks if SO_BROADCAST is enabled
+ *
+ * @return Whether SO_BROADCAST is set
+ *
+ * @exception SocketException If an error occurs
+ *
+ * @since 1.4
+ */
+ public boolean getBroadcast() throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ Object buf = getImpl().getOption(SocketOptions.SO_BROADCAST);
+
+ if (buf instanceof Boolean)
+ return ((Boolean) buf).booleanValue();
+
+ throw new SocketException("unexpected type");
+ }
+
+ /**
+ * Sets the traffic class value
+ *
+ * @param tc The traffic class
+ *
+ * @exception SocketException If an error occurs
+ * @exception IllegalArgumentException If tc value is illegal
+ *
+ * @see DatagramSocket#getTrafficClass()
+ *
+ * @since 1.4
+ */
+ public void setTrafficClass(int tc) throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ if (tc < 0 || tc > 255)
+ throw new IllegalArgumentException();
+
+ getImpl().setOption(SocketOptions.IP_TOS, new Integer(tc));
+ }
+
+ /**
+ * Returns the current traffic class
+ *
+ * @return The current traffic class.
+ *
+ * @see DatagramSocket#setTrafficClass(int tc)
+ *
+ * @exception SocketException If an error occurs
+ *
+ * @since 1.4
+ */
+ public int getTrafficClass() throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ Object buf = getImpl().getOption(SocketOptions.IP_TOS);
+
+ if (buf instanceof Integer)
+ return ((Integer) buf).intValue();
+
+ throw new SocketException("unexpected type");
+ }
+
+ /**
+ * Sets the datagram socket implementation factory for the application
+ *
+ * @param fac The factory to set
+ *
+ * @exception IOException If an error occurs
+ * @exception SocketException If the factory is already defined
+ * @exception SecurityException If a security manager exists and its
+ * checkSetFactory method doesn't allow the operation
+ */
+ public static void setDatagramSocketImplFactory(DatagramSocketImplFactory fac)
+ throws IOException
+ {
+ if (factory != null)
+ throw new SocketException("DatagramSocketImplFactory already defined");
+
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkSetFactory();
+
+ factory = fac;
+ }
+}