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.DatagramSocket;
22import java.net.InetAddress;
23import java.net.NetworkInterface;
24import java.net.SocketAddress;
25import java.nio.ByteBuffer;
26import java.nio.channels.spi.AbstractSelectableChannel;
27import java.nio.channels.spi.SelectorProvider;
28import java.util.Set;
29
30/**
31 * A {@code DatagramChannel} is a selectable channel that represents a partial
32 * abstraction of a datagram socket. The {@code socket} method of this class can
33 * return the related {@code DatagramSocket} instance, which can handle the
34 * socket.
35 * <p>
36 * A datagram channel is open but not connected when created with the
37 * {@code open()} method. After it is connected, it will keep the connected
38 * status until it is disconnected or closed. The benefit of a connected channel
39 * is the reduced effort of security checks during send and receive. When
40 * invoking {@code read} or {@code write}, a connected channel is required.
41 * <p>
42 * Datagram channels are thread-safe; only one thread can read or write at the
43 * same time.
44 */
45public abstract class DatagramChannel extends AbstractSelectableChannel
46        implements ByteChannel, ScatteringByteChannel, GatheringByteChannel {
47
48    /**
49     * Constructs a new {@code DatagramChannel}.
50     *
51     * @param selectorProvider
52     *            an instance of SelectorProvider.
53     */
54    protected DatagramChannel(SelectorProvider selectorProvider) {
55        super(selectorProvider);
56    }
57
58    /**
59     * Creates an opened and not-connected datagram channel.
60     * <p>
61     * This channel is created by calling the <code>openDatagramChannel</code>
62     * method of the default {@link SelectorProvider} instance.
63     *
64     * @return the new channel which is open but not connected.
65     * @throws IOException
66     *             if some I/O error occurs.
67     */
68    public static DatagramChannel open() throws IOException {
69        return SelectorProvider.provider().openDatagramChannel();
70    }
71
72    /**
73     * Gets the valid operations of this channel. Datagram channels support read
74     * and write operations, so this method returns (
75     * <code>SelectionKey.OP_READ</code> | <code>SelectionKey.OP_WRITE</code> ).
76     *
77     * @see java.nio.channels.SelectableChannel#validOps()
78     * @return valid operations in bit-set.
79     */
80    @Override
81    public final int validOps() {
82        return (SelectionKey.OP_READ | SelectionKey.OP_WRITE);
83    }
84
85    /**
86     * Returns the related datagram socket of this channel, which does not
87     * define additional public methods to those defined by
88     * {@link DatagramSocket}.
89     *
90     * @return the related DatagramSocket instance.
91     */
92    public abstract DatagramSocket socket();
93
94    /**
95     * Returns whether this channel's socket is connected or not.
96     *
97     * @return <code>true</code> if this channel's socket is connected;
98     *         <code>false</code> otherwise.
99     */
100    public abstract boolean isConnected();
101
102    /**
103     * Connects the socket of this channel to a remote address, which is the
104     * only communication peer for getting and sending datagrams after being
105     * connected.
106     * <p>
107     * This method can be called at any time without affecting the read and
108     * write operations being processed at the time the method is called. The
109     * connection status does not change until the channel is disconnected or
110     * closed.
111     * <p>
112     * This method executes the same security checks as the connect method of
113     * the {@link DatagramSocket} class.
114     *
115     * @param address
116     *            the address to be connected to.
117     * @return this channel.
118     * @throws ClosedChannelException
119     *             if the channel is already closed.
120     * @throws AsynchronousCloseException
121     *             if the channel is closed by another thread while this method
122     *             is in operation.
123     * @throws ClosedByInterruptException
124     *             if another thread interrupts the calling thread while the
125     *             operation is in progress. The calling thread will have the
126     *             interrupt state set and the channel will be closed.
127     * @throws IOException
128     *             if some other I/O error occurs.
129     */
130    public abstract DatagramChannel connect(SocketAddress address)
131            throws IOException;
132
133    /**
134     * Disconnects the socket of this channel, which has been connected before
135     * in order to send and receive datagrams.
136     * <p>
137     * This method can be called at any time without affecting the read and
138     * write operations being underway. It does not have any effect if the
139     * socket is not connected or the channel is closed.
140     *
141     * @return this channel.
142     * @throws IOException
143     *             some other I/O error occurs.
144     */
145    public abstract DatagramChannel disconnect() throws IOException;
146
147    /**
148     * Gets a datagram from this channel.
149     * <p>
150     * This method transfers a datagram from the channel into the target byte
151     * buffer. If this channel is in blocking mode, it waits for the datagram
152     * and returns its address when it is available. If this channel is in
153     * non-blocking mode and no datagram is available, it returns {@code null}
154     * immediately. The transfer starts at the current position of the buffer,
155     * and if there is not enough space remaining in the buffer to store the
156     * datagram then the part of the datagram that does not fit is discarded.
157     * <p>
158     * This method can be called at any time and it will block if there is
159     * another thread that has started a read operation on the channel.
160     * <p>
161     * This method executes the same security checks as the receive method of
162     * the {@link DatagramSocket} class.
163     *
164     * @param target
165     *            the byte buffer to store the received datagram.
166     * @return the address of the datagram if the transfer is performed, or null
167     *         if the channel is in non-blocking mode and no datagram is
168     *         available.
169     * @throws ClosedChannelException
170     *             if the channel is already closed.
171     * @throws AsynchronousCloseException
172     *             if the channel is closed by another thread while this method
173     *             is in operation.
174     * @throws ClosedByInterruptException
175     *             if another thread interrupts the calling thread while the
176     *             operation is in progress. The calling thread will have the
177     *             interrupt state set and the channel will be closed.
178     * @throws IOException
179     *             some other I/O error occurs.
180     */
181    public abstract SocketAddress receive(ByteBuffer target) throws IOException;
182
183    /**
184     * Sends a datagram through this channel. The datagram consists of the
185     * remaining bytes in {@code source}.
186     * <p>
187     * If this channel is in blocking mode then the datagram is sent as soon as
188     * there is enough space in the underlying output buffer. If this channel is
189     * in non-blocking mode then the datagram is only sent if there is enough
190     * space in the underlying output buffer at that moment. The transfer action
191     * is just like a regular write operation.
192     * <p>
193     * This method can be called at any time and it will block if another thread
194     * has started a send operation on this channel.
195     * <p>
196     * This method executes the same security checks as the send method of the
197     * {@link DatagramSocket} class.
198     *
199     * @param source
200     *            the byte buffer with the datagram to be sent.
201     * @param address
202     *            the destination address for the datagram.
203     * @return the number of bytes sent. This is the number of bytes remaining
204     *         in {@code source} or zero if the channel is in non-blocking mode
205     *         and there is not enough space for the datagram in the underlying
206     *         output buffer.
207     * @throws ClosedChannelException
208     *             if the channel is already closed.
209     * @throws AsynchronousCloseException
210     *             if the channel is closed by another thread while this method
211     *             is in operation.
212     * @throws ClosedByInterruptException
213     *             if another thread interrupts the calling thread while the
214     *             operation is in progress. The calling thread will have the
215     *             interrupt state set and the channel will be closed.
216     * @throws IOException
217     *             some other I/O error occurs.
218     */
219    public abstract int send(ByteBuffer source, SocketAddress address) throws IOException;
220
221    /**
222     * Reads a datagram from this channel into the byte buffer.
223     * <p>
224     * The precondition for calling this method is that the channel is connected
225     * and the incoming datagram is from the connected address. If the buffer is
226     * not big enough to store the datagram, the part of the datagram that does
227     * not fit in the buffer is discarded. Otherwise, this method has the same
228     * behavior as the {@code read} method in the {@link ReadableByteChannel}
229     * interface.
230     *
231     * @see java.nio.channels.ReadableByteChannel#read(java.nio.ByteBuffer)
232     * @param target
233     *            the byte buffer to store the received datagram.
234     * @return a non-negative number as the number of bytes read, or -1 as the
235     *         read operation reaches the end of stream.
236     * @throws NotYetConnectedException
237     *             if the channel is not connected yet.
238     * @throws ClosedChannelException
239     *             if the channel is already closed.
240     * @throws AsynchronousCloseException
241     *             if the channel is closed by another thread while this method
242     *             is in operation.
243     * @throws ClosedByInterruptException
244     *             if another thread interrupts the calling thread while the
245     *             operation is in progress. The calling thread will have the
246     *             interrupt state set and the channel will be closed.
247     * @throws IOException
248     *             some other I/O error occurs.
249     */
250    public abstract int read(ByteBuffer target) throws IOException;
251
252    /**
253     * Reads a datagram from this channel into an array of byte buffers.
254     * <p>
255     * The precondition for calling this method is that the channel is connected
256     * and the incoming datagram is from the connected address. If the buffers
257     * do not have enough remaining space to store the datagram, the part of the
258     * datagram that does not fit in the buffers is discarded. Otherwise, this
259     * method has the same behavior as the {@code read} method in the
260     * {@link ScatteringByteChannel} interface.
261     *
262     * @see java.nio.channels.ScatteringByteChannel#read(java.nio.ByteBuffer[],
263     *      int, int)
264     * @param targets
265     *            the byte buffers to store the received datagram.
266     * @param offset
267     *            a non-negative offset in the array of buffers, pointing to the
268     *            starting buffer to store the bytes transferred, must not be
269     *            bigger than {@code targets.length}.
270     * @param length
271     *            a non-negative length to indicate the maximum number of
272     *            buffers to be filled, must not be bigger than
273     *            {@code targets.length - offset}.
274     * @return a non-negative number as the number of bytes read, or -1 if the
275     *         read operation reaches the end of stream.
276     * @throws NotYetConnectedException
277     *             if the channel is not connected yet.
278     * @throws ClosedChannelException
279     *             if the channel is already closed.
280     * @throws AsynchronousCloseException
281     *             if the channel is closed by another thread while this method
282     *             is in operation.
283     * @throws ClosedByInterruptException
284     *             if another thread interrupts the calling thread while the
285     *             operation is in progress. The calling thread will have the
286     *             interrupt state set and the channel will be closed.
287     * @throws IOException
288     *             some other I/O error occurs.
289     */
290    public abstract long read(ByteBuffer[] targets, int offset, int length)
291            throws IOException;
292
293    /**
294     * Reads a datagram from this channel into an array of byte buffers.
295     * <p>
296     * The precondition for calling this method is that the channel is connected
297     * and the incoming datagram is from the connected address. If the buffers
298     * do not have enough remaining space to store the datagram, the part of the
299     * datagram that does not fit in the buffers is discarded. Otherwise, this
300     * method has the same behavior as the {@code read} method in the
301     * {@link ScatteringByteChannel} interface.
302     *
303     * @see java.nio.channels.ScatteringByteChannel#read(java.nio.ByteBuffer[])
304     * @param targets
305     *            the byte buffers to store the received datagram.
306     * @return a non-negative number as the number of bytes read, or -1 if the
307     *         read operation reaches the end of stream.
308     * @throws NotYetConnectedException
309     *             if the channel is not connected yet.
310     * @throws ClosedChannelException
311     *             if the channel is already closed.
312     * @throws AsynchronousCloseException
313     *             if the channel is closed by another thread while this method
314     *             is in operation.
315     * @throws ClosedByInterruptException
316     *             if another thread interrupts the calling thread while the
317     *             operation is in progress. The calling thread will have the
318     *             interrupt state set and the channel will be closed.
319     * @throws IOException
320     *             some other I/O error occurs.
321     */
322    public synchronized final long read(ByteBuffer[] targets)
323            throws IOException {
324        return read(targets, 0, targets.length);
325    }
326
327    /**
328     * Writes a datagram from the byte buffer to this channel.
329     * <p>
330     * The precondition of calling this method is that the channel is connected
331     * and the datagram is sent to the connected address. Otherwise, this method
332     * has the same behavior as the {@code write} method in the
333     * {@link WritableByteChannel} interface.
334     *
335     * @see java.nio.channels.WritableByteChannel#write(java.nio.ByteBuffer)
336     * @param source
337     *            the byte buffer as the source of the datagram.
338     * @return a non-negative number of bytes written.
339     * @throws NotYetConnectedException
340     *             if the channel is not connected yet.
341     * @throws ClosedChannelException
342     *             if the channel is already closed.
343     * @throws AsynchronousCloseException
344     *             if the channel is closed by another thread while this method
345     *             is in operation.
346     * @throws ClosedByInterruptException
347     *             if another thread interrupts the calling thread while the
348     *             operation is in progress. The calling thread will have the
349     *             interrupt state set and the channel will be closed.
350     * @throws IOException
351     *             some other I/O error occurs.
352     */
353    public abstract int write(ByteBuffer source) throws IOException;
354
355    /**
356     * Writes a datagram from the byte buffers to this channel.
357     * <p>
358     * The precondition of calling this method is that the channel is connected
359     * and the datagram is sent to the connected address. Otherwise, this method
360     * has the same behavior as the {@code write} method in the
361     * {@link GatheringByteChannel} interface.
362     *
363     * @see java.nio.channels.GatheringByteChannel#write(java.nio.ByteBuffer[],
364     *      int, int)
365     * @param sources
366     *            the byte buffers as the source of the datagram.
367     * @param offset
368     *            a non-negative offset in the array of buffers, pointing to the
369     *            starting buffer to be retrieved, must be no larger than
370     *            {@code sources.length}.
371     * @param length
372     *            a non-negative length to indicate the maximum number of
373     *            buffers to be submitted, must be no bigger than
374     *            {@code sources.length - offset}.
375     * @return the number of bytes written. If this method is called, it returns
376     *         the number of bytes that where remaining in the byte buffers. If
377     *         the channel is in non-blocking mode and there was not enough
378     *         space for the datagram in the buffer, it may return zero.
379     * @throws NotYetConnectedException
380     *             if the channel is not connected yet.
381     * @throws ClosedChannelException
382     *             if the channel is already closed.
383     * @throws AsynchronousCloseException
384     *             if the channel is closed by another thread while this method
385     *             is in operation.
386     * @throws ClosedByInterruptException
387     *             if another thread interrupts the calling thread while the
388     *             operation is in progress. The calling thread will have the
389     *             interrupt state set and the channel will be closed.
390     * @throws IOException
391     *             some other I/O error occurs.
392     */
393    public abstract long write(ByteBuffer[] sources, int offset, int length)
394            throws IOException;
395
396    /**
397     * Writes a datagram from the byte buffers to this channel.
398     * <p>
399     * The precondition of calling this method is that the channel is connected
400     * and the datagram is sent to the connected address. Otherwise, this method
401     * has the same behavior as the write method in the
402     * {@link GatheringByteChannel} interface.
403     *
404     * @see java.nio.channels.GatheringByteChannel#write(java.nio.ByteBuffer[])
405     * @param sources
406     *            the byte buffers as the source of the datagram.
407     * @return the number of bytes written. If this method is called, it returns
408     *         the number of bytes that where remaining in the byte buffer. If
409     *         the channel is in non-blocking mode and there was not enough
410     *         space for the datagram in the buffer, it may return zero.
411     * @throws NotYetConnectedException
412     *             if the channel is not connected yet.
413     * @throws ClosedChannelException
414     *             if the channel is already closed.
415     * @throws AsynchronousCloseException
416     *             if the channel is closed by another thread while this method
417     *             is in operation.
418     * @throws ClosedByInterruptException
419     *             if another thread interrupts the calling thread while the
420     *             operation is in progress. The calling thread will have the
421     *             interrupt state set and the channel will be closed.
422     * @throws IOException
423     *             some other I/O error occurs.
424     */
425    public synchronized final long write(ByteBuffer[] sources)
426            throws IOException {
427        return write(sources, 0, sources.length);
428    }
429}
430