001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package java.nio.channels;
019:
020: import java.io.IOException;
021: import java.net.Socket;
022: import java.net.SocketAddress;
023: import java.nio.ByteBuffer;
024: import java.nio.channels.spi.AbstractSelectableChannel;
025: import java.nio.channels.spi.SelectorProvider;
026:
027: import org.apache.harmony.luni.platform.Platform;
028:
029: /**
030: * A SocketChannel is a selectable channel for part abstraction of stream
031: * connecting socket. The <code>socket</code> method of this class can return
032: * the related <code>Socket</code> instance, which can handle the socket.
033: * <p>
034: * A socket channel is open but not connected when created by <code>open</code>
035: * method. After connected by calling the <code>connect</code> method, it will
036: * keep connected before closed. The connection is non-blocking that the
037: * <code>connect</code> method is for the initial connection and following
038: * <code>finishConnect</code> method is for the final steps of connection. The
039: * <code>isConnectionPending</code> method can tell the connection is blocked
040: * or not; the <code>isConnected</code> method can tell the socket is
041: * connected finally or not.
042: * </p>
043: * <p>
044: * The shut down operation can be independent and asynchronous for input and
045: * output. The <code>shutdownInput</code> method is for input, and can make
046: * the following read operation fail as end of stream. If the input is shut down
047: * and another thread is pending in read operation, the read will end without
048: * effect and return end of stream. The <code>shutdownOutput</code> method is
049: * for output, and can make the following write operation throwing a
050: * <code>ClosedChannelException</code>. If the output is shut down and
051: * another is pending in a write operation, an
052: * <code>AsynchronousCloseException</code> will thrown to the pending thread.
053: * </p>
054: * <p>
055: * Socket channels are thread-safe, no more than one thread can read or write at
056: * given time. The <code>connect</code> and <code>finishConnect</code>
057: * methods are concurrent each other, when they are processing, other read and
058: * write will block.
059: * </p>
060: */
061: public abstract class SocketChannel extends AbstractSelectableChannel
062: implements ByteChannel, ScatteringByteChannel,
063: GatheringByteChannel {
064:
065: static {
066: Platform.getNetworkSystem().oneTimeInitialization(true);
067: }
068:
069: /**
070: * Constructor for this class.
071: *
072: * @param selectorProvider
073: * A instance of SelectorProvider
074: */
075: protected SocketChannel(SelectorProvider selectorProvider) {
076: super (selectorProvider);
077: }
078:
079: /**
080: * Create a open and not-connected socket channel.
081: * <p>
082: * This channel is got by <code>openSocketChannel</code> method of the
083: * default <code>SelectorProvider </code> instance.
084: * </p>
085: *
086: * @return The new created channel which is open but not-connected.
087: * @throws IOException
088: * If some IO problem occurs.
089: */
090: public static SocketChannel open() throws IOException {
091: return SelectorProvider.provider().openSocketChannel();
092: }
093:
094: /**
095: * Create a socket channel and connect it to a socket address.
096: * <p>
097: * This method perform just as <code>open</code> method following by the
098: * <code>connect</code> method.
099: * </p>
100: *
101: * @param address
102: * The socket address to be connected.
103: * @return The new opened channel.
104: * @throws AsynchronousCloseException
105: * If the channel is closed by another thread while this method
106: * is in operation.
107: * @throws ClosedByInterruptException
108: * If another thread interrupts the calling thread while the
109: * operation is in progress. The calling thread will have the
110: * interrupt state set, and the channel will be closed.
111: * @throws UnresolvedAddressException
112: * If the address is not resolved.
113: * @throws UnsupportedAddressTypeException
114: * If the address type is not supported.
115: * @throws SecurityException
116: * If there is a security manager, and the address is not
117: * permitted to access.
118: * @throws IOException
119: * Some other IO error occurred.
120: *
121: */
122: public static SocketChannel open(SocketAddress address)
123: throws IOException {
124: SocketChannel socketChannel = open();
125: if (null != socketChannel) {
126: socketChannel.connect(address);
127: }
128: return socketChannel;
129: }
130:
131: /**
132: * Get the valid operations of this channel. Socket channels support
133: * connect, read and write operation, so this method returns (
134: * <code>SelectionKey.OP_CONNECT</code> |
135: * <code>SelectionKey.OP_READ</code> | <code>SelectionKey.OP_WRITE</code> ).
136: *
137: * @see java.nio.channels.SelectableChannel#validOps()
138: * @return Valid operations in bit-set.
139: */
140: @Override
141: public final int validOps() {
142: return (SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE);
143: }
144:
145: /**
146: * Return the related socket of this channel, which won't declare public
147: * methods that not declared in <code>Socket</code>.
148: *
149: * @return The related Socket instance.
150: */
151: public abstract Socket socket();
152:
153: /**
154: * Answer whether this channel's socket is connected or not.
155: *
156: * @return <code>true</code> for this channel's socket is connected;
157: * <code>false</code> otherwise.
158: */
159: public abstract boolean isConnected();
160:
161: /**
162: * Answer whether this channel's socket is in connecting or not.
163: *
164: * @return <code>true</code> for the connection is initiated but not
165: * finished; <code>false</code> otherwise.
166: */
167: public abstract boolean isConnectionPending();
168:
169: /**
170: * Connect the socket to remote address.
171: * <p>
172: * If the channel is blocking, this method will suspend before connection
173: * finished or an I/O exception. If the channel is non-blocking, this method
174: * will return <code>true</code> if the connection is finished at once or
175: * return <code>false</code> and the connection must wait
176: * <code>finishConnect</code> to finished otherwise.
177: * </p>
178: * <p>
179: * This method can be called at any moment, and can block other read and
180: * write operations while connecting.
181: * </p>
182: * <p>
183: * This method just execute the same security checks as the connect method
184: * of the <code>Socket</code> class.
185: * </p>
186: *
187: * @param address
188: * The address to be connected.
189: * @return <code>true</code> if connection is finished,<code>false</code>
190: * otherwise.
191: * @throws AlreadyConnectedException
192: * If the channel is connected already.
193: * @throws ConnectionPendingException
194: * A non-blocking connecting is doing on this channel.
195: * @throws ClosedChannelException
196: * If the channel is already closed.
197: * @throws AsynchronousCloseException
198: * If the channel is closed by another thread while this method
199: * is in operation.
200: * @throws ClosedByInterruptException
201: * If another thread interrupts the calling thread while the
202: * operation is in progress. The calling thread will have the
203: * interrupt state set, and the channel will be closed.
204: * @throws UnresolvedAddressException
205: * If the address is not resolved.
206: * @throws UnsupportedAddressTypeException
207: * If the address type is not supported.
208: * @throws SecurityException
209: * If there is a security manager, and the address is not
210: * permitted to access.
211: * @throws IOException
212: * Some other IO error occurred.
213: */
214: public abstract boolean connect(SocketAddress address)
215: throws IOException;
216:
217: /**
218: * Complete the connection.
219: * <p>
220: * This method is used when the channel is connectable to finish the
221: * connection, and the connectable status of a channel means the channel is
222: * after initiating in non-blocking mode and calling its
223: * <code>connect</code> method. It will throw related
224: * <code>IOException</code> if the connection failed.
225: * </p>
226: * <p>
227: * This method will return <code>true</code> if the connection is finished
228: * already, and return <code>false</code> if the channel is non-blocking
229: * and the connection is not finished yet.
230: * </p>
231: * <p>
232: * If the channel is in blocking mode, this method will suspend, and return
233: * <code>true</code> for connection finished or throw some exception
234: * otherwise. The channel will be closed if the connection failed and this
235: * method thrown some exception.
236: * </p>
237: * <p>
238: * This method can be called at any moment, and can block other read and
239: * write operations while connecting.
240: * </p>
241: *
242: * @return <code>true</code> if the connection is successfully finished,
243: * <code>false</code> otherwise.
244: * @throws NoConnectionPendingException
245: * If the channel is not connected and the connection is not
246: * initiated.
247: * @throws ClosedChannelException
248: * If the channel is already closed.
249: * @throws AsynchronousCloseException
250: * If the channel is closed by another thread while this method
251: * is in operation.
252: * @throws ClosedByInterruptException
253: * If another thread interrupts the calling thread while the
254: * operation is in progress. The calling thread will have the
255: * interrupt state set, and the channel will be closed.
256: * @throws IOException
257: * Some other IO error occurred.
258: */
259: public abstract boolean finishConnect() throws IOException;
260:
261: /**
262: * Reads bytes from the channel into the given buffer.
263: * <p>
264: * The maximum number of bytes that will be read is the
265: * <code>remaining()</code> number of bytes in the buffer when the method
266: * invoked. The bytes will be read into the buffer starting at the buffer's
267: * <code>position</code>.
268: * </p>
269: * <p>
270: * The call may block if other threads are also attempting to read on the
271: * same channel.
272: * </p>
273: * <p>
274: * Upon completion, the buffer's <code>position()</code> is updated to the
275: * end of the bytes that were read. The buffer's <code>limit()</code> is
276: * unmodified.
277: * </p>
278: *
279: * @see java.nio.channels.ReadableByteChannel#read(java.nio.ByteBuffer)
280: * @param target
281: * The byte buffer to receive the bytes.
282: * @return The number of bytes actually read.
283: * @throws NotYetConnectedException
284: * If the channel is not connected yet.
285: * @throws ClosedChannelException
286: * If the channel is already closed.
287: * @throws AsynchronousCloseException
288: * If the channel is closed by another thread while this method
289: * is in operation.
290: * @throws ClosedByInterruptException
291: * If another thread interrupts the calling thread while the
292: * operation is in progress. The calling thread will have the
293: * interrupt state set, and the channel will be closed.
294: * @throws IOException
295: * Some other IO error occurred.
296: */
297: public abstract int read(ByteBuffer target) throws IOException;
298:
299: /**
300: * Reads bytes from the channel into a subset of the given buffers.
301: * <p>
302: * This method attempts to read all of the <code>remaining()</code> bytes
303: * from <code>length</code> byte buffers, in order, starting at
304: * <code>targets[offset]</code>. The number of bytes actually read is
305: * returned.
306: * </p>
307: * <p>
308: * If a read operation is in progress, subsequent threads will block until
309: * the read is completed, and will then contend for the ability to read.
310: * </p>
311: *
312: * @see java.nio.channels.ScatteringByteChannel#read(java.nio.ByteBuffer[],
313: * int, int)
314: * @param targets
315: * the array of byte buffers into which the bytes will be read.
316: * @param offset
317: * the index of the first buffer to read.
318: * @param length
319: * the maximum number of buffers to read.
320: * @throws NotYetConnectedException
321: * If the channel is not connected yet.
322: * @throws ClosedChannelException
323: * If the channel is already closed.
324: * @throws AsynchronousCloseException
325: * If the channel is closed by another thread while this method
326: * is in operation.
327: * @throws ClosedByInterruptException
328: * If another thread interrupts the calling thread while the
329: * operation is in progress. The calling thread will have the
330: * interrupt state set, and the channel will be closed.
331: * @throws IOException
332: * Some other IO error occurred.
333: *
334: */
335: public abstract long read(ByteBuffer[] targets, int offset,
336: int length) throws IOException;
337:
338: /**
339: * Reads bytes from the channel into all the given buffers.
340: * <p>
341: * This method is equivalent to:
342: *
343: * <pre>
344: * read(targets, 0, targets.length);
345: * </pre>
346: *
347: * @see java.nio.channels.ScatteringByteChannel#read(java.nio.ByteBuffer[])
348: * @param targets
349: * the array of byte buffers to receive the bytes being read.
350: * @return the number of bytes actually read.
351: * @throws NotYetConnectedException
352: * If the channel is not connected yet.
353: * @throws ClosedChannelException
354: * If the channel is already closed.
355: * @throws AsynchronousCloseException
356: * If the channel is closed by another thread while this method
357: * is in operation.
358: * @throws ClosedByInterruptException
359: * If another thread interrupts the calling thread while the
360: * operation is in progress. The calling thread will have the
361: * interrupt state set, and the channel will be closed.
362: * @throws IOException
363: * Some other IO error occurred.
364: */
365: public synchronized final long read(ByteBuffer[] targets)
366: throws IOException {
367: return read(targets, 0, targets.length);
368: }
369:
370: /**
371: * Writes bytes from the given buffer to the channel.
372: * <p>
373: * The maximum number of bytes that will be written is the
374: * <code>remaining()</code> number of bytes in the buffer when the method
375: * invoked. The bytes will be written from the buffer starting at the
376: * buffer's <code>position</code>.
377: * </p>
378: * <p>
379: * The call may block if other threads are also attempting to write on the
380: * same channel.
381: * </p>
382: * <p>
383: * Upon completion, the buffer's <code>position()</code> is updated to the
384: * end of the bytes that were written. The buffer's <code>limit()</code>
385: * is unmodified.
386: * </p>
387: *
388: * @see java.nio.channels.WritableByteChannel#write(java.nio.ByteBuffer)
389: * @param source
390: * the byte buffer containing the bytes to be written.
391: * @return the number of bytes actually written.
392: * @throws NotYetConnectedException
393: * If the channel is not connected yet.
394: * @throws ClosedChannelException
395: * If the channel is already closed.
396: * @throws AsynchronousCloseException
397: * If the channel is closed by another thread while this method
398: * is in operation.
399: * @throws ClosedByInterruptException
400: * If another thread interrupts the calling thread while the
401: * operation is in progress. The calling thread will have the
402: * interrupt state set, and the channel will be closed.
403: * @throws IOException
404: * Some other IO error occurred.
405: */
406: public abstract int write(ByteBuffer source) throws IOException;
407:
408: /**
409: * Writes a subset of the given bytes from the buffers to the channel.
410: * <p>
411: * This method attempts to write all of the <code>remaining()</code> bytes
412: * from <code>length</code> byte buffers, in order, starting at
413: * <code>sources[offset]</code>. The number of bytes actually written is
414: * returned.
415: * </p>
416: * <p>
417: * If a write operation is in progress, subsequent threads will block until
418: * the write is completed, and will then contend for the ability to write.
419: * </p>
420: *
421: * @see java.nio.channels.GatheringByteChannel#write(java.nio.ByteBuffer[],
422: * int, int)
423: * @param sources
424: * the array of byte buffers containing the source of remaining
425: * bytes that will be attempted to be written.
426: * @param offset
427: * the index of the first buffer to write.
428: * @param length
429: * the number of buffers to write.
430: * @return the number of bytes actually written.
431: * @throws NotYetConnectedException
432: * If the channel is not connected yet.
433: * @throws ClosedChannelException
434: * If the channel is already closed.
435: * @throws AsynchronousCloseException
436: * If the channel is closed by another thread while this method
437: * is in operation.
438: * @throws ClosedByInterruptException
439: * If another thread interrupts the calling thread while the
440: * operation is in progress. The calling thread will have the
441: * interrupt state set, and the channel will be closed.
442: * @throws IOException
443: * Some other IO error occurred.
444: */
445: public abstract long write(ByteBuffer[] sources, int offset,
446: int length) throws IOException;
447:
448: /**
449: * Writes bytes from all the given buffers to the channel.
450: * <p>
451: * This method is equivalent to:
452: *
453: * <pre>
454: * write(buffers, 0, buffers.length);
455: * </pre>
456: *
457: * </p>
458: *
459: * @see java.nio.channels.GatheringByteChannel#write(java.nio.ByteBuffer[])
460: * @param sources
461: * the buffers containing bytes to be written.
462: * @return the number of bytes actually written.
463: * @throws NotYetConnectedException
464: * If the channel is not connected yet.
465: * @throws ClosedChannelException
466: * If the channel is already closed.
467: * @throws AsynchronousCloseException
468: * If the channel is closed by another thread while this method
469: * is in operation.
470: * @throws ClosedByInterruptException
471: * If another thread interrupts the calling thread while the
472: * operation is in progress. The calling thread will have the
473: * interrupt state set, and the channel will be closed.
474: * @throws IOException
475: * Some other IO error occurred.
476: */
477: public synchronized final long write(ByteBuffer[] sources)
478: throws IOException {
479: return write(sources, 0, sources.length);
480: }
481: }
|