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