blob: dd09e16d4ac73813776f48d65753381ed82517dc [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package java.nio.channels;
import java.io.IOException;
import java.net.DatagramSocket;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.spi.AbstractSelectableChannel;
import java.nio.channels.spi.SelectorProvider;
/**
* A {@code DatagramChannel} is a selectable channel that represents a partial
* abstraction of a datagram socket. The {@code socket} method of this class can
* return the related {@code DatagramSocket} instance, which can handle the
* socket.
* <p>
* A datagram channel is open but not connected when created with the
* {@code open()} method. After it is connected, it will keep the connected
* status until it is disconnected or closed. The benefit of a connected channel
* is the reduced effort of security checks during send and receive. When
* invoking {@code read} or {@code write}, a connected channel is required.
* <p>
* Datagram channels are thread-safe; only one thread can read or write at the
* same time.
*/
public abstract class DatagramChannel extends AbstractSelectableChannel
implements ByteChannel, ScatteringByteChannel, GatheringByteChannel {
/**
* Constructs a new {@code DatagramChannel}.
*
* @param selectorProvider
* an instance of SelectorProvider.
*/
protected DatagramChannel(SelectorProvider selectorProvider) {
super(selectorProvider);
}
/**
* Creates an opened and not-connected datagram channel.
* <p>
* This channel is created by calling the <code>openDatagramChannel</code>
* method of the default {@link SelectorProvider} instance.
*
* @return the new channel which is open but not connected.
* @throws IOException
* if some I/O error occurs.
*/
public static DatagramChannel open() throws IOException {
return SelectorProvider.provider().openDatagramChannel();
}
/**
* Gets the valid operations of this channel. Datagram channels support read
* and write operations, so this method returns (
* <code>SelectionKey.OP_READ</code> | <code>SelectionKey.OP_WRITE</code> ).
*
* @see java.nio.channels.SelectableChannel#validOps()
* @return valid operations in bit-set.
*/
@Override
public final int validOps() {
return (SelectionKey.OP_READ | SelectionKey.OP_WRITE);
}
/**
* Returns the related datagram socket of this channel, which does not
* define additional public methods to those defined by
* {@link DatagramSocket}.
*
* @return the related DatagramSocket instance.
*/
public abstract DatagramSocket socket();
/**
* Returns whether this channel's socket is connected or not.
*
* @return <code>true</code> if this channel's socket is connected;
* <code>false</code> otherwise.
*/
public abstract boolean isConnected();
/**
* Connects the socket of this channel to a remote address, which is the
* only communication peer for getting and sending datagrams after being
* connected.
* <p>
* This method can be called at any time without affecting the read and
* write operations being processed at the time the method is called. The
* connection status does not change until the channel is disconnected or
* closed.
* <p>
* This method executes the same security checks as the connect method of
* the {@link DatagramSocket} class.
*
* @param address
* the address to be connected to.
* @return this channel.
* @throws ClosedChannelException
* if the channel is already closed.
* @throws AsynchronousCloseException
* if the channel is closed by another thread while this method
* is in operation.
* @throws ClosedByInterruptException
* if another thread interrupts the calling thread while the
* operation is in progress. The calling thread will have the
* interrupt state set and the channel will be closed.
* @throws SecurityException
* if there is a security manager, and the address is not
* permitted to be accessed.
* @throws IOException
* if some other I/O error occurrs.
*/
public abstract DatagramChannel connect(SocketAddress address)
throws IOException;
/**
* Disconnects the socket of this channel, which has been connected before
* in order to send and receive datagrams.
* <p>
* This method can be called at any time without affecting the read and
* write operations being underway. It does not have any effect if the
* socket is not connected or the channel is closed.
*
* @return this channel.
* @throws IOException
* some other I/O error occurs.
*/
public abstract DatagramChannel disconnect() throws IOException;
/**
* Gets a datagram from this channel.
* <p>
* This method transfers a datagram from the channel into the target byte
* buffer. If this channel is in blocking mode, it waits for the datagram
* and returns its address when it is available. If this channel is in
* non-blocking mode and no datagram is available, it returns {@code null}
* immediately. The transfer starts at the current position of the buffer,
* and if there is not enough space remaining in the buffer to store the
* datagram then the part of the datagram that does not fit is discarded.
* <p>
* This method can be called at any time and it will block if there is
* another thread that has started a read operation on the channel.
* <p>
* This method executes the same security checks as the receive method of
* the {@link DatagramSocket} class.
*
* @param target
* the byte buffer to store the received datagram.
* @return the address of the datagram if the transfer is performed, or null
* if the channel is in non-blocking mode and no datagram is
* available.
* @throws ClosedChannelException
* if the channel is already closed.
* @throws AsynchronousCloseException
* if the channel is closed by another thread while this method
* is in operation.
* @throws ClosedByInterruptException
* if another thread interrupts the calling thread while the
* operation is in progress. The calling thread will have the
* interrupt state set and the channel will be closed.
* @throws SecurityException
* if there is a security manager, and the address is not
* permitted to be accessed.
* @throws IOException
* some other I/O error occurs.
*/
public abstract SocketAddress receive(ByteBuffer target) throws IOException;
/**
* Sends a datagram through this channel. The datagram consists of the
* remaining bytes in {@code source}.
* <p>
* If this channel is in blocking mode then the datagram is sent as soon as
* there is enough space in the underlying output buffer. If this channel is
* in non-blocking mode then the datagram is only sent if there is enough
* space in the underlying output buffer at that moment. The transfer action
* is just like a regular write operation.
* <p>
* This method can be called at any time and it will block if another thread
* has started a send operation on this channel.
* <p>
* This method executes the same security checks as the send method of the
* {@link DatagramSocket} class.
*
* @param source
* the byte buffer with the datagram to be sent.
* @param address
* the destination address for the datagram.
* @return the number of bytes sent. This is the number of bytes remaining
* in {@code source} or zero if the channel is in non-blocking mode
* and there is not enough space for the datagram in the underlying
* output buffer.
* @throws ClosedChannelException
* if the channel is already closed.
* @throws AsynchronousCloseException
* if the channel is closed by another thread while this method
* is in operation.
* @throws ClosedByInterruptException
* if another thread interrupts the calling thread while the
* operation is in progress. The calling thread will have the
* interrupt state set and the channel will be closed.
* @throws SecurityException
* if there is a security manager, and the address is not
* permitted to access.
* @throws IOException
* some other I/O error occurs.
*/
public abstract int send(ByteBuffer source, SocketAddress address)
throws IOException;
/**
* Reads a datagram from this channel into the byte buffer.
* <p>
* The precondition for calling this method is that the channel is connected
* and the incoming datagram is from the connected address. If the buffer is
* not big enough to store the datagram, the part of the datagram that does
* not fit in the buffer is discarded. Otherwise, this method has the same
* behavior as the {@code read} method in the {@link ReadableByteChannel}
* interface.
*
* @see java.nio.channels.ReadableByteChannel#read(java.nio.ByteBuffer)
* @param target
* the byte buffer to store the received datagram.
* @return a non-negative number as the number of bytes read, or -1 as the
* read operation reaches the end of stream.
* @throws NotYetConnectedException
* if the channel is not connected yet.
* @throws ClosedChannelException
* if the channel is already closed.
* @throws AsynchronousCloseException
* if the channel is closed by another thread while this method
* is in operation.
* @throws ClosedByInterruptException
* if another thread interrupts the calling thread while the
* operation is in progress. The calling thread will have the
* interrupt state set and the channel will be closed.
* @throws IOException
* some other I/O error occurs.
*/
public abstract int read(ByteBuffer target) throws IOException;
/**
* Reads a datagram from this channel into an array of byte buffers.
* <p>
* The precondition for calling this method is that the channel is connected
* and the incoming datagram is from the connected address. If the buffers
* do not have enough remaining space to store the datagram, the part of the
* datagram that does not fit in the buffers is discarded. Otherwise, this
* method has the same behavior as the {@code read} method in the
* {@link ScatteringByteChannel} interface.
*
* @see java.nio.channels.ScatteringByteChannel#read(java.nio.ByteBuffer[],
* int, int)
* @param targets
* the byte buffers to store the received datagram.
* @param offset
* a non-negative offset in the array of buffers, pointing to the
* starting buffer to store the bytes transferred, must not be
* bigger than {@code targets.length}.
* @param length
* a non-negative length to indicate the maximum number of
* buffers to be filled, must not be bigger than
* {@code targets.length - offset}.
* @return a non-negative number as the number of bytes read, or -1 if the
* read operation reaches the end of stream.
* @throws NotYetConnectedException
* if the channel is not connected yet.
* @throws ClosedChannelException
* if the channel is already closed.
* @throws AsynchronousCloseException
* if the channel is closed by another thread while this method
* is in operation.
* @throws ClosedByInterruptException
* if another thread interrupts the calling thread while the
* operation is in progress. The calling thread will have the
* interrupt state set and the channel will be closed.
* @throws IOException
* some other I/O error occurs.
*/
public abstract long read(ByteBuffer[] targets, int offset, int length)
throws IOException;
/**
* Reads a datagram from this channel into an array of byte buffers.
* <p>
* The precondition for calling this method is that the channel is connected
* and the incoming datagram is from the connected address. If the buffers
* do not have enough remaining space to store the datagram, the part of the
* datagram that does not fit in the buffers is discarded. Otherwise, this
* method has the same behavior as the {@code read} method in the
* {@link ScatteringByteChannel} interface.
*
* @see java.nio.channels.ScatteringByteChannel#read(java.nio.ByteBuffer[])
* @param targets
* the byte buffers to store the received datagram.
* @return a non-negative number as the number of bytes read, or -1 if the
* read operation reaches the end of stream.
* @throws NotYetConnectedException
* if the channel is not connected yet.
* @throws ClosedChannelException
* if the channel is already closed.
* @throws AsynchronousCloseException
* if the channel is closed by another thread while this method
* is in operation.
* @throws ClosedByInterruptException
* if another thread interrupts the calling thread while the
* operation is in progress. The calling thread will have the
* interrupt state set and the channel will be closed.
* @throws IOException
* some other I/O error occurs.
*/
public synchronized final long read(ByteBuffer[] targets)
throws IOException {
return read(targets, 0, targets.length);
}
/**
* Writes a datagram from the byte buffer to this channel.
* <p>
* The precondition of calling this method is that the channel is connected
* and the datagram is sent to the connected address. Otherwise, this method
* has the same behavior as the {@code write} method in the
* {@link WritableByteChannel} interface.
*
* @see java.nio.channels.WritableByteChannel#write(java.nio.ByteBuffer)
* @param source
* the byte buffer as the source of the datagram.
* @return a non-negative number of bytes written.
* @throws NotYetConnectedException
* if the channel is not connected yet.
* @throws ClosedChannelException
* if the channel is already closed.
* @throws AsynchronousCloseException
* if the channel is closed by another thread while this method
* is in operation.
* @throws ClosedByInterruptException
* if another thread interrupts the calling thread while the
* operation is in progress. The calling thread will have the
* interrupt state set and the channel will be closed.
* @throws IOException
* some other I/O error occurs.
*/
public abstract int write(ByteBuffer source) throws IOException;
/**
* Writes a datagram from the byte buffers to this channel.
* <p>
* The precondition of calling this method is that the channel is connected
* and the datagram is sent to the connected address. Otherwise, this method
* has the same behavior as the {@code write} method in the
* {@link GatheringByteChannel} interface.
*
* @see java.nio.channels.GatheringByteChannel#write(java.nio.ByteBuffer[],
* int, int)
* @param sources
* the byte buffers as the source of the datagram.
* @param offset
* a non-negative offset in the array of buffers, pointing to the
* starting buffer to be retrieved, must be no larger than
* {@code sources.length}.
* @param length
* a non-negative length to indicate the maximum number of
* buffers to be submitted, must be no bigger than
* {@code sources.length - offset}.
* @return the number of bytes written. If this method is called, it returns
* the number of bytes that where remaining in the byte buffers. If
* the channel is in non-blocking mode and there was not enough
* space for the datagram in the buffer, it may return zero.
* @throws NotYetConnectedException
* if the channel is not connected yet.
* @throws ClosedChannelException
* if the channel is already closed.
* @throws AsynchronousCloseException
* if the channel is closed by another thread while this method
* is in operation.
* @throws ClosedByInterruptException
* if another thread interrupts the calling thread while the
* operation is in progress. The calling thread will have the
* interrupt state set and the channel will be closed.
* @throws IOException
* some other I/O error occurs.
*/
public abstract long write(ByteBuffer[] sources, int offset, int length)
throws IOException;
/**
* Writes a datagram from the byte buffers to this channel.
* <p>
* The precondition of calling this method is that the channel is connected
* and the datagram is sent to the connected address. Otherwise, this method
* has the same behavior as the write method in the
* {@link GatheringByteChannel} interface.
*
* @see java.nio.channels.GatheringByteChannel#write(java.nio.ByteBuffer[])
* @param sources
* the byte buffers as the source of the datagram.
* @return the number of bytes written. If this method is called, it returns
* the number of bytes that where remaining in the byte buffer. If
* the channel is in non-blocking mode and there was not enough
* space for the datagram in the buffer, it may return zero.
* @throws NotYetConnectedException
* if the channel is not connected yet.
* @throws ClosedChannelException
* if the channel is already closed.
* @throws AsynchronousCloseException
* if the channel is closed by another thread while this method
* is in operation.
* @throws ClosedByInterruptException
* if another thread interrupts the calling thread while the
* operation is in progress. The calling thread will have the
* interrupt state set and the channel will be closed.
* @throws IOException
* some other I/O error occurs.
*/
public synchronized final long write(ByteBuffer[] sources)
throws IOException {
return write(sources, 0, sources.length);
}
}