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.DatagramSocket;
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 DatagramChannel is a selectable channel for part abstraction of datagram
031: * socket. The <code>socket</code> method of this class can return the related
032: * <code>DatagramSocket</code> instance, which can handle the socket.
033: * <p>
034: * A datagram channel is open but not connected when created by
035: * <code>open</code> method. After connected, it will keep the connected
036: * status before disconnecting or closing. The benefit of a connected channel is
037: * the reduced effort of security checks during send and receive. When invoking
038: * <code>read</code> or <code>write</code>, a connected channel is
039: * required.
040: * </p>
041: * <p>
042: * Datagram channels are thread-safe, no more than one thread can read or write
043: * at given time.
044: * </p>
045: */
046: public abstract class DatagramChannel extends AbstractSelectableChannel
047: implements ByteChannel, ScatteringByteChannel,
048: GatheringByteChannel {
049:
050: static {
051: Platform.getNetworkSystem().oneTimeInitialization(true);
052: }
053:
054: /**
055: * Constructor for this class.
056: *
057: * @param selectorProvider
058: * A instance of SelectorProvider
059: */
060: protected DatagramChannel(SelectorProvider selectorProvider) {
061: super (selectorProvider);
062: }
063:
064: /**
065: * Create a open and not-connected datagram channel.
066: * <p>
067: * This channel is got by <code>openDatagramChannel</code> method of the
068: * default <code>SelectorProvider </code> instance.
069: * </p>
070: *
071: * @return The new created channel which is open but not-connected.
072: * @throws IOException
073: * If some IO problem occurs.
074: */
075: public static DatagramChannel open() throws IOException {
076: return SelectorProvider.provider().openDatagramChannel();
077: }
078:
079: /**
080: * Get the valid operations of this channel. Datagram channels support read
081: * and write operation, so this method returns (
082: * <code>SelectionKey.OP_READ</code> | <code>SelectionKey.OP_WRITE</code> ).
083: *
084: * @see java.nio.channels.SelectableChannel#validOps()
085: * @return Valid operations in bit-set.
086: */
087: @Override
088: public final int validOps() {
089: return (SelectionKey.OP_READ | SelectionKey.OP_WRITE);
090: }
091:
092: /**
093: * Return the related datagram socket of this channel, which won't declare
094: * public methods that not declared in <code>DatagramSocket</code>.
095: *
096: * @return The related DatagramSocket instance.
097: */
098: public abstract DatagramSocket socket();
099:
100: /**
101: * Answer whether this channel's socket is connected or not.
102: *
103: * @return <code>true</code> for this channel's socket is connected;
104: * <code>false</code> otherwise.
105: */
106: public abstract boolean isConnected();
107:
108: /**
109: * Connect the socket of this channel to a remote address, which is the only
110: * communication peer of getting and sending datagrams after connected.
111: * <p>
112: * This method can be called at any moment, and won't affect the processing
113: * read and write operation. The connect status won't changed before
114: * disconnected and closed.
115: * </p>
116: * <p>
117: * This method just execute the same security checks as the connect method
118: * of the <code>DatagramSocket</code> class.
119: * </p>
120: *
121: * @param address
122: * The address to be connected.
123: * @return This channel.
124: * @throws ClosedChannelException
125: * If the channel is already closed.
126: * @throws AsynchronousCloseException
127: * If the channel is closed by another thread while this method
128: * is in operation.
129: * @throws ClosedByInterruptException
130: * If another thread interrupts the calling thread while the
131: * operation is in progress. The calling thread will have the
132: * interrupt state set, and the channel will be closed.
133: * @throws SecurityException
134: * If there is a security manager, and the address is not
135: * permitted to access.
136: * @throws IOException
137: * Some other IO error occurred.
138: */
139: public abstract DatagramChannel connect(SocketAddress address)
140: throws IOException;
141:
142: /**
143: * Disconnect the socket of this channel, which is connected before for
144: * getting and sending datagrams.
145: * <p>
146: * This method can be called at any moment, and won't affect the processing
147: * read and write operation. It won't has any effect if the socket is not
148: * connected or the channel is closed.
149: * </p>
150: *
151: * @return This channel.
152: * @throws IOException
153: * Some other IO error occurred.
154: */
155: public abstract DatagramChannel disconnect() throws IOException;
156:
157: /**
158: * Get a datagram from this channel.
159: * <p>
160: * This method transfers the datagram from the channel into the target byte
161: * buffer and return the address of the datagram, if the datagram is
162: * available or will be available as this channel is in blocking mode. This
163: * method returns <code>null</code> if the datagram is not available now
164: * and the channel is in non-blocking mode. The transfer start at the
165: * current position of the buffer, and the residual part of the datagram
166: * will be ignored if there is no efficient remaining in the buffer to store
167: * the datagram.
168: * </p>
169: * <p>
170: * This method can be called at any moment, and will block if there is
171: * another thread started a read operation on the channel.
172: * </p>
173: * <p>
174: * This method just execute the same security checks as the receive method
175: * of the <code>DatagramSocket</code> class.
176: * </p>
177: *
178: * @param target
179: * The byte buffer to store the received datagram.
180: * @return Address of the datagram if the transfer is performed, or null if
181: * the channel is in non-blocking mode and the datagram are
182: * unavailable.
183: * @throws ClosedChannelException
184: * If the channel is already closed.
185: * @throws AsynchronousCloseException
186: * If the channel is closed by another thread while this method
187: * is in operation.
188: * @throws ClosedByInterruptException
189: * If another thread interrupts the calling thread while the
190: * operation is in progress. The calling thread will have the
191: * interrupt state set, and the channel will be closed.
192: * @throws SecurityException
193: * If there is a security manager, and the address is not
194: * permitted to access.
195: * @throws IOException
196: * Some other IO error occurred.
197: */
198: public abstract SocketAddress receive(ByteBuffer target)
199: throws IOException;
200:
201: /**
202: * Sends out a datagram by the channel.
203: * <p>
204: * The precondition of sending is that whether the channel is in blocking
205: * mode and enough byte buffer space will be available, or the channel is in
206: * non-blocking mode and byte buffer space is enough. The transfer action is
207: * just like a regular write operation.
208: * </p>
209: * <p>
210: * This method can be called at any moment, and will block if there is
211: * another thread started a read operation on the channel.
212: * </p>
213: * <p>
214: * This method just execute the same security checks as the send method of
215: * the <code>DatagramSocket</code> class.
216: * </p>
217: *
218: * @param source
219: * The byte buffer with the datagram to be sent.
220: * @param address
221: * The address to be sent.
222: * @return The number of sent bytes. If this method is called, it returns
223: * the number of bytes that remaining in the byte buffer. If the
224: * channel is in non-blocking mode and no enough space for the
225: * datagram in the buffer, it may returns zero.
226: * @throws ClosedChannelException
227: * If the channel is already closed.
228: * @throws AsynchronousCloseException
229: * If the channel is closed by another thread while this method
230: * is in operation.
231: * @throws ClosedByInterruptException
232: * If another thread interrupts the calling thread while the
233: * operation is in progress. The calling thread will have the
234: * interrupt state set, and the channel will be closed.
235: * @throws SecurityException
236: * If there is a security manager, and the address is not
237: * permitted to access.
238: * @throws IOException
239: * Some other IO error occurred.
240: */
241: public abstract int send(ByteBuffer source, SocketAddress address)
242: throws IOException;
243:
244: /**
245: * Reads datagram from the channel into the byte buffer.
246: * <p>
247: * The precondition of calling this method is that the channel is connected
248: * and the coming datagram is from the connected address. If the buffer is
249: * not enough to store the datagram, the residual part of the datagram is
250: * ignored. Otherwise, this method has the same behavior as the read method
251: * in the <code>ReadableByteChannel</code> interface.
252: * </p>
253: *
254: * @see java.nio.channels.ReadableByteChannel#read(java.nio.ByteBuffer)
255: * @param target
256: * The byte buffer to store the received datagram.
257: * @return Non-negative number as the number of bytes read, or -1 as the
258: * read operation reaches the end of stream.
259: * @throws NotYetConnectedException
260: * If the channel is not connected yet.
261: * @throws ClosedChannelException
262: * If the channel is already closed.
263: * @throws AsynchronousCloseException
264: * If the channel is closed by another thread while this method
265: * is in operation.
266: * @throws ClosedByInterruptException
267: * If another thread interrupts the calling thread while the
268: * operation is in progress. The calling thread will have the
269: * interrupt state set, and the channel will be closed.
270: * @throws IOException
271: * Some other IO error occurred.
272: */
273: public abstract int read(ByteBuffer target) throws IOException;
274:
275: /**
276: * Reads datagram from the channel into the byte buffer.
277: * <p>
278: * The precondition of calling this method is that the channel is connected
279: * and the coming datagram is from the connected address. If the buffer is
280: * not enough to store the datagram, the residual part of the datagram is
281: * ignored. Otherwise, this method has the same behavior as the read method
282: * in the <code>ScatteringByteChannel</code> interface.
283: * </p>
284: *
285: * @see java.nio.channels.ScatteringByteChannel#read(java.nio.ByteBuffer[],
286: * int, int)
287: * @param targets
288: * The byte buffers to store the received datagram.
289: * @param offset
290: * A non-negative offset in the array of buffer, pointing to the
291: * starting buffer to store the byte transferred, must no larger
292: * than targets.length.
293: * @param length
294: * A non-negative length to indicate the maximum number of byte
295: * to be read, must no larger than targets.length - offset.
296: * @return Non-negative number as the number of bytes read, or -1 as the
297: * read operation reaches the end of stream.
298: * @throws NotYetConnectedException
299: * If the channel is not connected yet.
300: * @throws ClosedChannelException
301: * If the channel is already closed.
302: * @throws AsynchronousCloseException
303: * If the channel is closed by another thread while this method
304: * is in operation.
305: * @throws ClosedByInterruptException
306: * If another thread interrupts the calling thread while the
307: * operation is in progress. The calling thread will have the
308: * interrupt state set, and the channel will be closed.
309: * @throws IOException
310: * Some other IO error occurred.
311: */
312: public abstract long read(ByteBuffer[] targets, int offset,
313: int length) throws IOException;
314:
315: /**
316: * Reads datagram from the channel into the byte buffer.
317: * <p>
318: * The precondition of calling this method is that the channel is connected
319: * and the coming datagram is from the connected address. If the buffer is
320: * not enough to store the datagram, the residual part of the datagram is
321: * ignored. Otherwise, this method has the same behavior as the read method
322: * in the <code>ScatteringByteChannel</code> interface.
323: * </p>
324: *
325: * @see java.nio.channels.ScatteringByteChannel#read(java.nio.ByteBuffer[])
326: * @param targets
327: * The byte buffers to store the received datagram.
328: * @return Non-negative number as the number of bytes read, or -1 as the
329: * read operation reaches the end of stream.
330: * @throws NotYetConnectedException
331: * If the channel is not connected yet.
332: * @throws ClosedChannelException
333: * If the channel is already closed.
334: * @throws AsynchronousCloseException
335: * If the channel is closed by another thread while this method
336: * is in operation.
337: * @throws ClosedByInterruptException
338: * If another thread interrupts the calling thread while the
339: * operation is in progress. The calling thread will have the
340: * interrupt state set, and the channel will be closed.
341: * @throws IOException
342: * Some other IO error occurred.
343: */
344: public synchronized final long read(ByteBuffer[] targets)
345: throws IOException {
346: return read(targets, 0, targets.length);
347: }
348:
349: /**
350: * Write datagram from the byte buffer into the channel.
351: * <p>
352: * The precondition of calling this method is that the channel is connected
353: * and the datagram is sent to the connected address. Otherwise, this method
354: * has the same behavior as the write method in the
355: * <code>WritableByteChannel</code> interface.
356: * </p>
357: *
358: * @see java.nio.channels.WritableByteChannel#write(java.nio.ByteBuffer)
359: * @param source
360: * The byte buffer as the source of the datagram.
361: * @return Non-negative number of bytes written.
362: * @throws NotYetConnectedException
363: * If the channel is not connected yet.
364: * @throws ClosedChannelException
365: * If the channel is already closed.
366: * @throws AsynchronousCloseException
367: * If the channel is closed by another thread while this method
368: * is in operation.
369: * @throws ClosedByInterruptException
370: * If another thread interrupts the calling thread while the
371: * operation is in progress. The calling thread will have the
372: * interrupt state set, and the channel will be closed.
373: * @throws IOException
374: * Some other IO error occurred.
375: */
376: public abstract int write(ByteBuffer source) throws IOException;
377:
378: /**
379: * Write datagram from the byte buffer into the channel.
380: * <p>
381: * The precondition of calling this method is that the channel is connected
382: * and the datagram is sent to the connected address. Otherwise, this method
383: * has the same behavior as the write method in the
384: * <code>GatheringByteChannel</code> interface.
385: *
386: * @see java.nio.channels.GatheringByteChannel#write(java.nio.ByteBuffer[],
387: * int, int)
388: * @param sources
389: * The byte buffers as the source of the datagram.
390: * @param offset
391: * A non-negative offset in the array of buffer, pointing to the
392: * starting buffer to be retrieved, must no larger than
393: * sources.length.
394: * @param length
395: * A non-negative length to indicate the maximum number of byte
396: * to be written, must no larger than sources.length - offset.
397: * @return The number of written bytes. If this method is called, it returns
398: * the number of bytes that remaining in the byte buffer. If the
399: * channel is in non-blocking mode and no enough space for the
400: * datagram in the buffer, it may returns zero.
401: * @throws NotYetConnectedException
402: * If the channel is not connected yet.
403: * @throws ClosedChannelException
404: * If the channel is already closed.
405: * @throws AsynchronousCloseException
406: * If the channel is closed by another thread while this method
407: * is in operation.
408: * @throws ClosedByInterruptException
409: * If another thread interrupts the calling thread while the
410: * operation is in progress. The calling thread will have the
411: * interrupt state set, and the channel will be closed.
412: * @throws IOException
413: * Some other IO error occurred.
414: */
415: public abstract long write(ByteBuffer[] sources, int offset,
416: int length) throws IOException;
417:
418: /**
419: * Write datagram from the byte buffer into the channel.
420: * <p>
421: * The precondition of calling this method is that the channel is connected
422: * and the datagram is sent to the connected address. Otherwise, this method
423: * has the same behavior as the write method in the
424: * <code>GatheringByteChannel</code> interface.
425: *
426: * @see java.nio.channels.GatheringByteChannel#write(java.nio.ByteBuffer[])
427: * @param sources
428: * The byte buffers as the source of the datagram.
429: * @return The number of written bytes. If this method is called, it returns
430: * the number of bytes that remaining in the byte buffer. If the
431: * channel is in non-blocking mode and no enough space for the
432: * datagram in the buffer, it may returns zero.
433: * @throws NotYetConnectedException
434: * If the channel is not connected yet.
435: * @throws ClosedChannelException
436: * If the channel is already closed.
437: * @throws AsynchronousCloseException
438: * If the channel is closed by another thread while this method
439: * is in operation.
440: * @throws ClosedByInterruptException
441: * If another thread interrupts the calling thread while the
442: * operation is in progress. The calling thread will have the
443: * interrupt state set, and the channel will be closed.
444: * @throws IOException
445: * Some other IO error occurred.
446: */
447: public synchronized final long write(ByteBuffer[] sources)
448: throws IOException {
449: return write(sources, 0, sources.length);
450: }
451: }
|