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