1 /* PlainSocketImpl.java -- Default socket implementation
2 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
3 Free Software Foundation, Inc.
5 This file is part of GNU Classpath.
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING. If not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 Linking this library statically or dynamically with other modules is
23 making a combined work based on this library. Thus, the terms and
24 conditions of the GNU General Public License cover the whole
27 As a special exception, the copyright holders of this library give you
28 permission to link this library with independent modules to produce an
29 executable, regardless of the license terms of these independent
30 modules, and to copy and distribute the resulting executable under
31 terms of your choice, provided that you also meet, for each linked
32 independent module, the terms and conditions of the license of that
33 module. An independent module is a module which is not derived from
34 or based on this library. If you modify this library, you may extend
35 this exception to your version of the library, but you are not
36 obligated to do so. If you do not wish to do so, delete this
37 exception statement from your version. */
42 import gnu.classpath.Configuration;
44 import java.io.IOException;
45 import java.io.InputStream;
46 import java.io.OutputStream;
47 import java.net.InetAddress;
48 import java.net.InetSocketAddress;
49 import java.net.SocketAddress;
50 import java.net.SocketException;
51 import java.net.SocketImpl;
52 import java.net.SocketOptions;
55 * Written using on-line Java Platform 1.2 API Specification, as well
56 * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
57 * Status: Believed complete and correct.
61 * Unless the application installs its own SocketImplFactory, this is the
62 * default socket implemetation that will be used. It simply uses a
63 * combination of Java and native routines to implement standard BSD
64 * style sockets of family AF_INET and types SOCK_STREAM and SOCK_DGRAM
66 * @author Per Bothner (bothner@cygnus.com)
67 * @author Nic Ferrier (nferrier@tapsellferrier.co.uk)
68 * @author Aaron M. Renn (arenn@urbanophile.com)
70 public final class PlainSocketImpl extends SocketImpl
72 // Static initializer to load native library.
75 if (Configuration.INIT_LOAD_LIBRARY)
77 System.loadLibrary("javanet");
82 * The OS file handle representing the socket.
83 * This is used for reads and writes to/from the socket and
86 * When the socket is closed this is reset to -1.
91 * A cached copy of the in stream for reading from the socket.
93 private InputStream in;
96 * A cached copy of the out stream for writing to the socket.
98 private OutputStream out;
101 * Indicates whether a channel initiated whatever operation
102 * is being invoked on this socket.
104 private boolean inChannelOperation;
107 * Indicates whether we should ignore whether any associated
108 * channel is set to non-blocking mode. Certain operations
109 * throw an <code>IllegalBlockingModeException</code> if the
110 * associated channel is in non-blocking mode, <i>except</i>
111 * if the operation is invoked by the channel itself.
113 public final boolean isInChannelOperation()
115 return inChannelOperation;
119 * Sets our indicator of whether an I/O operation is being
120 * initiated by a channel.
122 public final void setInChannelOperation(boolean b)
124 inChannelOperation = b;
128 * Default do nothing constructor
130 public PlainSocketImpl()
134 protected void finalize() throws Throwable
143 catch (IOException ex)
150 public int getNativeFD()
156 * Sets the specified option on a socket to the passed in object. For
157 * options that take an integer argument, the passed in object is an
158 * Integer. The option_id parameter is one of the defined constants in
161 * @param option_id The identifier of the option
162 * @param val The value to set the option to
164 * @exception SocketException If an error occurs
166 public native void setOption(int optID, Object value) throws SocketException;
169 * Returns the current setting of the specified option. The Object returned
170 * will be an Integer for options that have integer values. The option_id
171 * is one of the defined constants in this interface.
173 * @param option_id The option identifier
175 * @return The current value of the option
177 * @exception SocketException If an error occurs
179 public native Object getOption(int optID) throws SocketException;
182 * Flushes the input stream and closes it. If you read from the input stream
183 * after calling this method a <code>IOException</code> will be thrown.
185 * @throws IOException if an error occurs
187 public native void shutdownInput() throws IOException;
190 * Flushes the output stream and closes it. If you write to the output stream
191 * after calling this method a <code>IOException</code> will be thrown.
193 * @throws IOException if an error occurs
195 public native void shutdownOutput() throws IOException;
198 * Creates a new socket that is not bound to any local address/port and
199 * is not connected to any remote address/port. This will be created as
200 * a stream socket if the stream parameter is true, or a datagram socket
201 * if the stream parameter is false.
203 * @param stream true for a stream socket, false for a datagram socket
205 protected synchronized native void create(boolean stream) throws IOException;
208 * Connects to the remote hostname and port specified as arguments.
210 * @param hostname The remote hostname to connect to
211 * @param port The remote port to connect to
213 * @exception IOException If an error occurs
215 protected synchronized void connect(String host, int port) throws IOException
217 connect(InetAddress.getByName(host), port);
221 * Connects to the remote address and port specified as arguments.
223 * @param addr The remote address to connect to
224 * @param port The remote port to connect to
226 * @exception IOException If an error occurs
228 protected native void connect(InetAddress addr, int port) throws IOException;
231 * Connects to the remote socket address with a specified timeout.
233 * @param timeout The timeout to use for this connect, 0 means infinite.
235 * @exception IOException If an error occurs
237 protected synchronized void connect(SocketAddress address, int timeout) throws IOException
239 InetSocketAddress sockAddr = (InetSocketAddress) address;
240 InetAddress addr = sockAddr.getAddress();
243 throw new IllegalArgumentException("address is unresolved: " + sockAddr);
245 int port = sockAddr.getPort();
248 throw new IllegalArgumentException("negative timeout");
250 Object oldTimeoutObj = null;
254 oldTimeoutObj = this.getOption (SocketOptions.SO_TIMEOUT);
255 this.setOption (SocketOptions.SO_TIMEOUT, new Integer (timeout));
256 connect (addr, port);
260 if (oldTimeoutObj != null)
261 this.setOption (SocketOptions.SO_TIMEOUT, oldTimeoutObj);
266 * Binds to the specified port on the specified addr. Note that this addr
267 * must represent a local IP address. **** How bind to INADDR_ANY? ****
269 * @param addr The address to bind to
270 * @param port The port number to bind to
272 * @exception IOException If an error occurs
274 protected synchronized native void bind(InetAddress addr, int port)
278 * Starts listening for connections on a socket. The queuelen parameter
279 * is how many pending connections will queue up waiting to be serviced
280 * before being accept'ed. If the queue of pending requests exceeds this
281 * number, additional connections will be refused.
283 * @param queuelen The length of the pending connection queue
285 * @exception IOException If an error occurs
287 protected synchronized native void listen(int queuelen)
291 * Accepts a new connection on this socket and returns in in the
292 * passed in SocketImpl.
294 * @param impl The SocketImpl object to accept this connection.
296 protected synchronized native void accept(SocketImpl impl)
300 * Returns the number of bytes that the caller can read from this socket
303 * @return The number of readable bytes before blocking
305 * @exception IOException If an error occurs
307 protected native int available() throws IOException;
310 * Closes the socket. This will cause any InputStream or OutputStream
311 * objects for this Socket to be closed as well.
313 * Note that if the SO_LINGER option is set on this socket, then the
314 * operation could block.
316 * @exception IOException If an error occurs
318 protected native void close() throws IOException;
320 public void sendUrgentData(int data)
322 throw new InternalError ("PlainSocketImpl::sendUrgentData not implemented");
326 * Internal method used by SocketInputStream for reading data from
327 * the connection. Reads up to len bytes of data into the buffer
328 * buf starting at offset bytes into the buffer.
330 * @return The actual number of bytes read or -1 if end of stream.
332 * @exception IOException If an error occurs
334 protected native int read(byte[] buf, int offset, int len)
338 * Internal method used by SocketOuputStream for writing data to
339 * the connection. Writes up to len bytes of data from the buffer
340 * buf starting at offset bytes into the buffer.
342 * @exception IOException If an error occurs
344 protected native void write(byte[] buf, int offset, int len)
348 * Returns an InputStream object for reading from this socket. This will
349 * be an instance of SocketInputStream.
351 * @return An input stream attached to the socket.
353 * @exception IOException If an error occurs
355 protected synchronized InputStream getInputStream() throws IOException
358 in = new SocketInputStream();
364 * Returns an OutputStream object for writing to this socket. This will
365 * be an instance of SocketOutputStream.
367 * @return An output stream attached to the socket.
369 * @exception IOException If an error occurs
371 protected synchronized OutputStream getOutputStream() throws IOException
374 out = new SocketOutputStream();
380 * This class contains an implementation of <code>InputStream</code> for
381 * sockets. It in an internal only class used by <code>PlainSocketImpl</code>.
383 * @author Nic Ferrier (nferrier@tapsellferrier.co.uk)
385 final class SocketInputStream
389 * Returns the number of bytes available to be read before blocking
391 public int available() throws IOException
393 return PlainSocketImpl.this.available();
397 * This method not only closes the stream, it closes the underlying socket
398 * (and thus any connection) and invalidates any other Input/Output streams
399 * for the underlying impl object
401 public void close() throws IOException
403 PlainSocketImpl.this.close();
407 * Reads the next byte of data and returns it as an int.
409 * @return The byte read (as an int) or -1 if end of stream);
411 * @exception IOException If an error occurs.
413 public int read() throws IOException
415 byte buf[] = new byte [1];
416 int bytes_read = read(buf, 0, 1);
418 if (bytes_read == -1)
421 return buf[0] & 0xFF;
425 * Reads up to len bytes of data into the caller supplied buffer starting
426 * at offset bytes from the start of the buffer
428 * @param buf The buffer
429 * @param offset Offset into the buffer to start reading from
430 * @param len The number of bytes to read
432 * @return The number of bytes actually read or -1 if end of stream
434 * @exception IOException If an error occurs.
436 public int read (byte[] buf, int offset, int len) throws IOException
438 int bytes_read = PlainSocketImpl.this.read (buf, offset, len);
448 * This class is used internally by <code>PlainSocketImpl</code> to be the
449 * <code>OutputStream</code> subclass returned by its
450 * <code>getOutputStream method</code>. It expects only to be used in that
453 * @author Nic Ferrier (nferrier@tapsellferrier.co.uk)
455 final class SocketOutputStream
459 * This method closes the stream and the underlying socket connection. This
460 * action also effectively closes any other InputStream or OutputStream
461 * object associated with the connection.
463 * @exception IOException If an error occurs
465 public void close() throws IOException
467 PlainSocketImpl.this.close();
471 * Writes a byte (passed in as an int) to the given output stream
473 * @param b The byte to write
475 * @exception IOException If an error occurs
477 public void write(int b) throws IOException
479 byte buf[] = { (byte) b };
484 * Writes len number of bytes from the array buf to the stream starting
485 * at offset bytes into the buffer.
487 * @param buf The buffer
488 * @param offset Offset into the buffer to start writing from
489 * @param len The number of bytes to write
491 * @exception IOException If an error occurs.
493 public void write (byte[] buf, int offset, int len) throws IOException
495 PlainSocketImpl.this.write (buf, offset, len);