Source for gnu.java.net.PlainDatagramSocketImpl

   1: /* PlainDatagramSocketImpl.java -- Default DatagramSocket implementation
   2:    Copyright (C) 1998, 1999, 2001, 2003, 2004, 2005, 2007  Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   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)
   9: any later version.
  10:  
  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.
  15: 
  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
  19: 02110-1301 USA.
  20: 
  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
  24: combination.
  25: 
  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. */
  37: 
  38: 
  39: package gnu.java.net;
  40: 
  41: import gnu.classpath.Configuration;
  42: 
  43: import java.io.IOException;
  44: import java.net.DatagramPacket;
  45: import java.net.DatagramSocketImpl;
  46: import java.net.InetAddress;
  47: import java.net.InetSocketAddress;
  48: import java.net.NetworkInterface;
  49: import java.net.SocketAddress;
  50: import java.net.SocketException;
  51: import java.net.SocketOptions;
  52: 
  53: /**
  54:  * Written using on-line Java Platform 1.2 API Specification, as well
  55:  * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
  56:  * Status:  Believed complete and correct.
  57:  */
  58: 
  59: /**
  60:  * This is the default socket implementation for datagram sockets.
  61:  * It makes native calls to C routines that implement BSD style
  62:  * SOCK_DGRAM sockets in the AF_INET family.
  63:  *
  64:  * @author Aaron M. Renn (arenn@urbanophile.com)
  65:  * @author Warren Levy (warrenl@cygnus.com)
  66:  */
  67: public final class PlainDatagramSocketImpl extends DatagramSocketImpl
  68: {
  69:   // Static initializer to load native library
  70:   static
  71:   {
  72:     if (Configuration.INIT_LOAD_LIBRARY)
  73:       {
  74:         System.loadLibrary("javanet");
  75:       }
  76:   }
  77:   
  78:   // These fields are mirrored for use in native code to avoid cpp conflicts
  79:   // when the #defines in system header files are the same as the public fields.
  80:   static final int _Jv_TCP_NODELAY_ = SocketOptions.TCP_NODELAY,
  81:                    _Jv_SO_BINDADDR_ = SocketOptions.SO_BINDADDR,
  82:                    _Jv_SO_REUSEADDR_ = SocketOptions.SO_REUSEADDR,
  83:                    _Jv_SO_BROADCAST_ = SocketOptions.SO_BROADCAST,
  84:                    _Jv_SO_OOBINLINE_ = SocketOptions.SO_OOBINLINE,
  85:                    _Jv_IP_MULTICAST_IF_ = SocketOptions.IP_MULTICAST_IF,
  86:                    _Jv_IP_MULTICAST_IF2_ = SocketOptions.IP_MULTICAST_IF2,
  87:                    _Jv_IP_MULTICAST_LOOP_ = SocketOptions.IP_MULTICAST_LOOP,
  88:                    _Jv_IP_TOS_ = SocketOptions.IP_TOS,
  89:                    _Jv_SO_LINGER_ = SocketOptions.SO_LINGER,
  90:                    _Jv_SO_TIMEOUT_ = SocketOptions.SO_TIMEOUT,
  91:                    _Jv_SO_SNDBUF_ = SocketOptions.SO_SNDBUF,
  92:                    _Jv_SO_RCVBUF_ = SocketOptions.SO_RCVBUF,
  93:                    _Jv_SO_KEEPALIVE_ = SocketOptions.SO_KEEPALIVE;
  94: 
  95:   /**
  96:    * This is the actual underlying file descriptor
  97:    */
  98:   int native_fd = -1;
  99:   
 100:   /**
 101:    * Lock object to serialize threads wanting to receive 
 102:    */
 103:   private final Object RECEIVE_LOCK = new Object();
 104:   
 105:   /**
 106:    * Lock object to serialize threads wanting to send 
 107:    */
 108:   private final Object SEND_LOCK = new Object();
 109: 
 110:   // FIXME: Is this necessary?  Could it help w/ DatagramSocket.getLocalAddress?
 111:   // InetAddress address;
 112:   
 113:   // localAddress cache  
 114:   InetAddress localAddress;
 115: 
 116:   // 'timeout' is set/read by setOption/getOption.
 117:   int timeout = 0;
 118: 
 119:   /**
 120:    * Default do nothing constructor
 121:    */
 122:   public PlainDatagramSocketImpl() throws IOException
 123:   {
 124:   }
 125: 
 126:   protected void finalize() throws Throwable
 127:   {
 128:     synchronized (this)
 129:       {
 130:     if (native_fd != -1)
 131:       close();
 132:       }
 133:     super.finalize();
 134:   }
 135: 
 136:   public int getNativeFD()
 137:   {
 138:     return native_fd;
 139:   }
 140: 
 141:   /**
 142:    * Binds this socket to a particular port and interface
 143:    *
 144:    * @param port The port to bind to
 145:    * @param addr The address to bind to
 146:    *
 147:    * @exception SocketException If an error occurs
 148:    */
 149:   protected native void bind(int port, InetAddress addr)
 150:     throws SocketException;
 151: 
 152:   protected native void connect(InetAddress addr, int port)
 153:     throws SocketException;
 154:   
 155:   protected native void disconnect();
 156:   
 157:   /**
 158:    * Creates a new datagram socket
 159:    *
 160:    * @exception SocketException If an error occurs
 161:    */
 162:   protected native void create() throws SocketException;
 163:   
 164:   protected native int peek(InetAddress addr) throws IOException;
 165:   
 166:   protected native int peekData(DatagramPacket packet) throws IOException;
 167: 
 168:   /**
 169:    * Sets the Time to Live value for the socket
 170:    *
 171:    * @param ttl The new TTL value
 172:    *
 173:    * @exception IOException If an error occurs
 174:    */
 175:   protected native void setTimeToLive(int ttl) throws IOException;
 176: 
 177:   /**
 178:    * Gets the Time to Live value for the socket
 179:    *
 180:    * @return The TTL value
 181:    *
 182:    * @exception IOException If an error occurs
 183:    */
 184:   protected native int getTimeToLive() throws IOException;
 185: 
 186:   /**
 187:    * Sends a packet of data to a remote host
 188:    *
 189:    * @param packet The packet to send
 190:    *
 191:    * @exception IOException If an error occurs
 192:    */
 193:   protected native void send(DatagramPacket packet) throws IOException;
 194: 
 195:   /**
 196:    * Receives a UDP packet from the network
 197:    *
 198:    * @param packet The packet to fill in with the data received
 199:    *
 200:    * @exception IOException IOException If an error occurs
 201:    */
 202:   protected native void receive(DatagramPacket packet) throws IOException;
 203: 
 204:   /**
 205:    * Sets the value of an option on the socket
 206:    *
 207:    * @param option_id The identifier of the option to set
 208:    * @param val The value of the option to set
 209:    *
 210:    * @exception SocketException If an error occurs
 211:    */
 212:   public native void setOption(int option_id, Object val)
 213:     throws SocketException;
 214: 
 215:   /**
 216:    * Retrieves the value of an option on the socket
 217:    *
 218:    * @param option_id The identifier of the option to retrieve
 219:    *
 220:    * @return The value of the option
 221:    *
 222:    * @exception SocketException If an error occurs
 223:    */
 224:   public native Object getOption(int option_id)
 225:     throws SocketException;
 226: 
 227:   /**
 228:    * Joins or leaves a broadcasting group on a given network interface.
 229:    * If the network interface is <code>null</code> the group is join/left on
 230:    * all locale network interfaces.
 231:    * 
 232:    * @param inetAddr The broadcast address.
 233:    * @param netIf The network interface to join the group on.
 234:    * @param join True to join a broadcasting group, fals to leave it.
 235:    *
 236:    * @exception IOException If an error occurs.
 237:    */
 238:   private native void mcastGrp(InetAddress inetAddr, NetworkInterface netIf,
 239:                        boolean join)
 240:     throws IOException;
 241: 
 242:   /**
 243:    * Closes the socket
 244:    */
 245:   protected native void close();
 246: 
 247:   /**
 248:    * Gets the Time to Live value for the socket
 249:    *
 250:    * @return The TTL value
 251:    *
 252:    * @exception IOException If an error occurs
 253:    *
 254:    * @deprecated 1.2
 255:    */
 256:   protected byte getTTL() throws IOException
 257:   {
 258:     return (byte) getTimeToLive();
 259:   }
 260: 
 261:   /**
 262:    * Sets the Time to Live value for the socket
 263:    *
 264:    * @param ttl The new TTL value
 265:    *
 266:    * @exception IOException If an error occurs
 267:    *
 268:    * @deprecated 1.2
 269:    */
 270:   protected void setTTL(byte ttl) throws IOException
 271:   {
 272:     setTimeToLive(((int) ttl) & 0xFF);
 273:   }
 274: 
 275:   /**
 276:    * Joins a multicast group
 277:    *
 278:    * @param addr The group to join
 279:    *
 280:    * @exception IOException If an error occurs
 281:    */
 282:   protected void join(InetAddress addr) throws IOException
 283:   {
 284:     mcastGrp(addr, null, true);
 285:   }
 286: 
 287:   /**
 288:    * Leaves a multicast group
 289:    *
 290:    * @param addr The group to leave
 291:    *
 292:    * @exception IOException If an error occurs
 293:    */
 294:   protected void leave(InetAddress addr) throws IOException
 295:   {
 296:     mcastGrp(addr, null, false);
 297:   }
 298: 
 299:   protected void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf)
 300:     throws IOException
 301:   {
 302:     mcastGrp(((InetSocketAddress) mcastaddr).getAddress(), netIf, true);
 303:   }
 304: 
 305:   protected void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf)
 306:     throws IOException
 307:   {
 308:     mcastGrp(((InetSocketAddress) mcastaddr).getAddress(), netIf, false);
 309:   }
 310: }