1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package java.nio.channels;
19
20import java.io.IOException;
21import java.net.Socket;
22import java.net.SocketAddress;
23import java.nio.ByteBuffer;
24import java.nio.channels.spi.AbstractSelectableChannel;
25import java.nio.channels.spi.SelectorProvider;
26
27/**
28 * A {@code SocketChannel} is a selectable channel that provides a partial
29 * abstraction of stream connecting socket. {@code socket()} returns the related
30 * {@link Socket} instance which can handle the socket.
31 * <p>
32 * A socket channel is open but not connected when created by {@code open()}.
33 * After connecting it by calling {@code connect(SocketAddress)}, it will remain
34 * connected until it gets closed. If the connection is non-blocking then
35 * {@code connect(SocketAddress)} is used to initiate the connection, followed
36 * by a call of {@code finishConnect()} to perform the final steps of
37 * connecting. {@code isConnectionPending()} indicates if the connection is
38 * blocked or not; {@code isConnected()} indicates if the socket is finally
39 * connected or not.
40 * <p>
41 * The input and output sides of a channel can be shut down independently and
42 * asynchronously without closing the channel. The {@code shutdownInput} method
43 * is used for the input side of a channel and subsequent read operations return
44 * -1, which means end of stream. If another thread is blocked in a read
45 * operation when the shutdown occurs, the read will end without effect and
46 * return end of stream. The {@code shutdownOutput} method is used for the
47 * output side of the channel; subsequent write operations throw a
48 * {@link ClosedChannelException}. If the output is shut down and another thread
49 * is blocked in a write operation, an {@link AsynchronousCloseException} will
50 * be thrown to the pending thread.
51 * <p>
52 * Socket channels are thread-safe, no more than one thread can read or write at
53 * any given time. The {@code connect(SocketAddress)} and {@code
54 * finishConnect()} methods are synchronized against each other; when they are
55 * processing, calls to {@code read} and {@code write} will block.
56 */
57public abstract class SocketChannel extends AbstractSelectableChannel implements
58        ByteChannel, ScatteringByteChannel, GatheringByteChannel {
59
60    /**
61     * Constructs a new {@code SocketChannel}.
62     *
63     * @param selectorProvider
64     *            an instance of SelectorProvider.
65     */
66    protected SocketChannel(SelectorProvider selectorProvider) {
67        super(selectorProvider);
68    }
69
70    /**
71     * Creates an open and unconnected socket channel.
72     * <p>
73     * This channel is created by calling {@code openSocketChannel()} of the
74     * default {@link SelectorProvider} instance.
75     *
76     * @return the new channel which is open but unconnected.
77     * @throws IOException
78     *             if an I/O error occurs.
79     */
80    public static SocketChannel open() throws IOException {
81        return SelectorProvider.provider().openSocketChannel();
82    }
83
84    /**
85     * Creates a socket channel and connects it to a socket address.
86     * <p>
87     * This method performs a call to {@code open()} followed by a call to
88     * {@code connect(SocketAddress)}.
89     *
90     * @param address
91     *            the socket address to be connected to.
92     * @return the new connected channel.
93     * @throws AsynchronousCloseException
94     *             if this channel is closed by another thread while this method
95     *             is executing.
96     * @throws ClosedByInterruptException
97     *             if another thread interrupts the calling thread while this
98     *             operation is executing. The calling thread will have the
99     *             interrupt state set and the channel will be closed.
100     * @throws UnresolvedAddressException
101     *             if the address is not resolved.
102     * @throws UnsupportedAddressTypeException
103     *             if the address type is not supported.
104     * @throws IOException
105     *             if an I/O error occurs.
106     */
107    public static SocketChannel open(SocketAddress address) throws IOException {
108        SocketChannel socketChannel = open();
109        if (socketChannel != null) {
110            socketChannel.connect(address);
111        }
112        return socketChannel;
113    }
114
115    /**
116     * Gets the valid operations of this channel. Socket channels support
117     * connect, read and write operation, so this method returns
118     * {@code SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE}.
119     *
120     * @return the operations supported by this channel.
121     * @see java.nio.channels.SelectableChannel#validOps()
122     */
123    @Override
124    public final int validOps() {
125        return (SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE);
126    }
127
128    /**
129     * Returns the socket assigned to this channel, which does not declare any public
130     * methods that are not declared in {@code Socket}.
131     *
132     * @return the socket assigned to this channel.
133     */
134    public abstract Socket socket();
135
136    /**
137     * Indicates whether this channel's socket is connected.
138     *
139     * @return {@code true} if this channel's socket is connected, {@code false}
140     *         otherwise.
141     */
142    public abstract boolean isConnected();
143
144    /**
145     * Indicates whether this channel's socket is still trying to connect.
146     *
147     * @return {@code true} if the connection is initiated but not finished;
148     *         {@code false} otherwise.
149     */
150    public abstract boolean isConnectionPending();
151
152    /**
153     * Connects this channel's socket with a remote address.
154     * <p>
155     * If this channel is blocking, this method will suspend until connecting is
156     * finished or an I/O exception occurs. If the channel is non-blocking,
157     * this method will return {@code true} if the connection is finished at
158     * once or return {@code false} when the connection must be finished later
159     * by calling {@code finishConnect()}.
160     * <p>
161     * This method can be called at any moment and can block other read and
162     * write operations while connecting. It executes the same security checks
163     * as the connect method of the {@code Socket} class.
164     *
165     * @param address
166     *            the address to connect with.
167     * @return {@code true} if the connection is finished, {@code false}
168     *         otherwise.
169     * @throws AlreadyConnectedException
170     *             if the channel is already connected.
171     * @throws ConnectionPendingException
172     *             a non-blocking connecting operation is already executing on
173     *             this channel.
174     * @throws ClosedChannelException
175     *             if this channel is closed.
176     * @throws AsynchronousCloseException
177     *             if this channel is closed by another thread while this method
178     *             is executing.
179     * @throws ClosedByInterruptException
180     *             if another thread interrupts the calling thread while this
181     *             operation is in progress. The calling thread will have the
182     *             interrupt state set and this channel will be closed.
183     * @throws UnresolvedAddressException
184     *             if the address is not resolved.
185     * @throws UnsupportedAddressTypeException
186     *             if the address type is not supported.
187     * @throws IOException
188     *             if an I/O error occurs.
189     */
190    public abstract boolean connect(SocketAddress address) throws IOException;
191
192    /**
193     * Completes the connection process initiated by a call of {@code
194     * connect(SocketAddress)}.
195     * <p>
196     * This method returns {@code true} if the connection is finished already
197     * and returns {@code false} if the channel is non-blocking and the
198     * connection is not finished yet.
199     * <p>
200     * If this channel is in blocking mode, this method will suspend and return
201     * {@code true} when the connection is finished. It closes this channel and
202     * throws an exception if the connection fails.
203     * <p>
204     * This method can be called at any moment and it can block other {@code
205     * read} and {@code write} operations while connecting.
206     *
207     * @return {@code true} if the connection is successfully finished, {@code
208     *         false} otherwise.
209     * @throws NoConnectionPendingException
210     *             if the channel is not connected and the connection process
211     *             has not been initiated.
212     * @throws ClosedChannelException
213     *             if this channel is closed.
214     * @throws AsynchronousCloseException
215     *             if this channel is closed by another thread while this method
216     *             is executing.
217     * @throws ClosedByInterruptException
218     *             if another thread interrupts the calling thread while this
219     *             operation is in progress. The calling thread has the
220     *             interrupt state set, and this channel is closed.
221     * @throws IOException
222     *             if an I/O error occurs.
223     */
224    public abstract boolean finishConnect() throws IOException;
225
226    /**
227     * Reads bytes from this socket channel into the given buffer.
228     * <p>
229     * The maximum number of bytes that will be read is the remaining number of
230     * bytes in the buffer when the method is invoked. The bytes will be copied
231     * into the buffer starting at the buffer's current position.
232     * <p>
233     * The call may block if other threads are also attempting to read from this
234     * channel.
235     * <p>
236     * Upon completion, the buffer's position is set to the end of the bytes
237     * that have been read. The buffer's limit is not changed.
238     *
239     * @param target
240     *            the byte buffer to receive the bytes.
241     * @return the number of bytes actually read.
242     * @throws AsynchronousCloseException
243     *             if another thread closes the channel during the read.
244     * @throws NotYetConnectedException
245     *             if this channel is not yet connected.
246     * @throws ClosedByInterruptException
247     *             if another thread interrupts the calling thread while this
248     *             operation is in progress. The interrupt state of the calling
249     *             thread is set and the channel is closed.
250     * @throws ClosedChannelException
251     *             if this channel is closed.
252     * @throws IOException
253     *             if another I/O error occurs.
254     * @see java.nio.channels.ReadableByteChannel#read(java.nio.ByteBuffer)
255     */
256    public abstract int read(ByteBuffer target) throws IOException;
257
258    /**
259     * Reads bytes from this socket channel into a subset of the given buffers.
260     * This method attempts to read all {@code remaining()} bytes from {@code
261     * length} byte buffers, in order, starting at {@code targets[offset]}. The
262     * number of bytes actually read is returned.
263     * <p>
264     * If a read operation is in progress, subsequent threads will block until
265     * the read is completed and will then contend for the ability to read.
266     *
267     * @param targets
268     *            the array of byte buffers into which the bytes will be copied.
269     * @param offset
270     *            the index of the first buffer to store bytes in.
271     * @param length
272     *            the maximum number of buffers to store bytes in.
273     * @return the number of bytes actually read.
274     * @throws AsynchronousCloseException
275     *             if this channel is closed by another thread during this read
276     *             operation.
277     * @throws ClosedByInterruptException
278     *             if another thread interrupts the calling thread while this
279     *             operation is in progress. The interrupt state of the calling
280     *             thread is set and the channel is closed.
281     * @throws ClosedChannelException
282     *             if this channel is closed.
283     * @throws IndexOutOfBoundsException
284     *             if {@code offset < 0} or {@code length < 0}, or if {@code
285     *             offset + length} is greater than the size of {@code targets}.
286     * @throws IOException
287     *             if another I/O error occurs.
288     * @throws NotYetConnectedException
289     *             if this channel is not yet connected.
290     * @see java.nio.channels.ScatteringByteChannel#read(java.nio.ByteBuffer[],
291     *      int, int)
292     */
293    public abstract long read(ByteBuffer[] targets, int offset, int length) throws IOException;
294
295    /**
296     * Reads bytes from this socket channel and stores them in the specified
297     * array of buffers. This method attempts to read as many bytes as can be
298     * stored in the buffer array from this channel and returns the number of
299     * bytes actually read.
300     * <p>
301     * If a read operation is in progress, subsequent threads will block until
302     * the read is completed and will then contend for the ability to read.
303     * <p>
304     * Calling this method is equivalent to calling {@code read(targets, 0,
305     * targets.length);}
306     *
307     * @param targets
308     *            the array of byte buffers into which the bytes will be copied.
309     * @return the number of bytes actually read.
310     * @throws AsynchronousCloseException
311     *             if this channel is closed by another thread during this read
312     *             operation.
313     * @throws ClosedByInterruptException
314     *             if another thread interrupts the calling thread while this
315     *             operation is in progress. The interrupt state of the calling
316     *             thread is set and the channel is closed.
317     * @throws ClosedChannelException
318     *             if this channel is closed.
319     * @throws IOException
320     *             if another I/O error occurs.
321     * @throws NotYetConnectedException
322     *             if this channel is not yet connected.
323     */
324    public synchronized final long read(ByteBuffer[] targets) throws IOException {
325        return read(targets, 0, targets.length);
326    }
327
328    /**
329     * Writes bytes from the given byte buffer to this socket channel. The
330     * maximum number of bytes that are written is the remaining number of bytes
331     * in the buffer when this method is invoked. The bytes are taken from the
332     * buffer starting at the buffer's position.
333     * <p>
334     * The call may block if other threads are also attempting to write to the
335     * same channel.
336     * <p>
337     * Upon completion, the buffer's position is updated to the end of the bytes
338     * that have been written. The buffer's limit is not changed.
339     *
340     * @param source
341     *            the byte buffer containing the bytes to be written.
342     * @return the number of bytes actually written.
343     * @throws AsynchronousCloseException
344     *             if another thread closes the channel during the write.
345     * @throws ClosedByInterruptException
346     *             if another thread interrupts the calling thread while this
347     *             operation is in progress. The interrupt state of the calling
348     *             thread is set and the channel is closed.
349     * @throws ClosedChannelException
350     *             if the channel was already closed.
351     * @throws IOException
352     *             if another I/O error occurs.
353     * @throws NotYetConnectedException
354     *             if this channel is not connected yet.
355     * @see java.nio.channels.WritableByteChannel#write(java.nio.ByteBuffer)
356     */
357    public abstract int write(ByteBuffer source) throws IOException;
358
359    /**
360     * Attempts to write a subset of the given bytes from the buffers to this
361     * socket channel. This method attempts to write all {@code remaining()}
362     * bytes from {@code length} byte buffers, in order, starting at {@code
363     * sources[offset]}. The number of bytes actually written is returned.
364     * <p>
365     * If a write operation is in progress, subsequent threads will block until
366     * the write is completed and then contend for the ability to write.
367     *
368     * @param sources
369     *            the array of byte buffers that is the source for bytes written
370     *            to this channel.
371     * @param offset
372     *            the index of the first buffer in {@code buffers }to get bytes
373     *            from.
374     * @param length
375     *            the number of buffers to get bytes from.
376     * @return the number of bytes actually written to this channel.
377     * @throws AsynchronousCloseException
378     *             if this channel is closed by another thread during this write
379     *             operation.
380     * @throws ClosedByInterruptException
381     *             if another thread interrupts the calling thread while this
382     *             operation is in progress. The interrupt state of the calling
383     *             thread is set and the channel is closed.
384     * @throws ClosedChannelException
385     *             if this channel is closed.
386     * @throws IndexOutOfBoundsException
387     *             if {@code offset < 0} or {@code length < 0}, or if {@code
388     *             offset + length} is greater than the size of {@code sources}.
389     * @throws IOException
390     *             if another I/O error occurs.
391     * @throws NotYetConnectedException
392     *             if this channel is not yet connected.
393     * @see java.nio.channels.GatheringByteChannel#write(java.nio.ByteBuffer[],
394     *      int, int)
395     */
396    public abstract long write(ByteBuffer[] sources, int offset, int length) throws IOException;
397
398    /**
399     * Writes bytes from all the given byte buffers to this socket channel.
400     * <p>
401     * Calling this method is equivalent to calling {@code write(sources, 0,
402     * sources.length);}
403     *
404     * @param sources
405     *            the buffers containing bytes to write.
406     * @return the number of bytes actually written.
407     * @throws AsynchronousCloseException
408     *             if this channel is closed by another thread during this write
409     *             operation.
410     * @throws ClosedByInterruptException
411     *             if another thread interrupts the calling thread while this
412     *             operation is in progress. The interrupt state of the calling
413     *             thread is set and the channel is closed.
414     * @throws ClosedChannelException
415     *             if this channel is closed.
416     * @throws IOException
417     *             if another I/O error occurs.
418     * @throws NotYetConnectedException
419     *             if this channel is not yet connected.
420     * @see java.nio.channels.GatheringByteChannel#write(java.nio.ByteBuffer[])
421     */
422    public synchronized final long write(ByteBuffer[] sources) throws IOException {
423        return write(sources, 0, sources.length);
424    }
425}
426