DatagramChannelImplpublic class DatagramChannelImpl extends DatagramChannel implements org.apache.harmony.luni.platform.FileDescriptorHandler
Fields Summary |
---|
private static final org.apache.harmony.luni.platform.INetworkSystem | networkSystem | private static final int | DEFAULT_TIMEOUT | private static final int | ERRCODE_SOCKET_NONBLOCKING_WOULD_BLOCK | private static final byte[] | stubArray | private FileDescriptor | fd | private DatagramSocket | socket | InetSocketAddress | connectAddress | private int | localPort | boolean | connected | boolean | isBound | private final Object | readLock | private final Object | writeLock | private int | trafficClass |
Constructors Summary |
---|
protected DatagramChannelImpl(SelectorProvider selectorProvider)
// -------------------------------------------------------------------
// Constructor
// -------------------------------------------------------------------
/*
* Constructor
*/
super(selectorProvider);
fd = new FileDescriptor();
networkSystem.createDatagramSocket(fd, true);
| private DatagramChannelImpl()
super(SelectorProvider.provider());
fd = new FileDescriptor();
connectAddress = new InetSocketAddress(0);
|
Methods Summary |
---|
private int | calculateByteBufferArray(java.nio.ByteBuffer[] sources, int offset, int length)
int sum = 0;
for (int val = offset; val < offset + length; val++) {
sum += sources[val].remaining();
}
return sum;
| private void | checkNotNull(java.nio.ByteBuffer source)
if (null == source) {
throw new NullPointerException();
}
| private void | checkOpen()
if (!isOpen()) {
throw new ClosedChannelException();
}
| private void | checkOpenConnected()
checkOpen();
if (!isConnected()) {
throw new NotYetConnectedException();
}
| private void | checkWritable(java.nio.ByteBuffer target)
// including checking of NPE.
if (target.isReadOnly()) {
throw new IllegalArgumentException();
}
| public synchronized java.nio.channels.DatagramChannel | connect(java.net.SocketAddress address)
// must open
checkOpen();
// status must be un-connected.
if (connected) {
throw new IllegalStateException();
}
// check the address
InetSocketAddress inetSocketAddress = SocketChannelImpl
.validateAddress(address);
// security check
SecurityManager sm = System.getSecurityManager();
if (null != sm) {
if (inetSocketAddress.getAddress().isMulticastAddress()) {
sm.checkMulticast(inetSocketAddress.getAddress());
} else {
sm.checkConnect(inetSocketAddress.getAddress().getHostName(),
inetSocketAddress.getPort());
}
}
try {
begin();
networkSystem.connectDatagram(fd, inetSocketAddress.getPort(),
trafficClass, inetSocketAddress.getAddress());
} catch (ConnectException e) {
// ConnectException means connect fail, not exception
} finally {
end(true);
}
// set the connected address.
connectAddress = inetSocketAddress;
connected = true;
isBound = true;
return this;
| public synchronized java.nio.channels.DatagramChannel | disconnect()
if (!isConnected() || !isOpen()) {
return this;
}
connected = false;
connectAddress = null;
networkSystem.disconnectDatagram(fd);
if (null != socket) {
socket.disconnect();
}
return this;
| public java.io.FileDescriptor | getFD()
return fd;
| java.net.InetAddress | getLocalAddress()Answer the local address from the IP stack. This method should not be
called directly as it does not check the security policy.
return networkSystem.getSocketLocalAddress(fd, NetUtil
.preferIPv6Addresses());
| protected synchronized void | implCloseSelectableChannel()
connected = false;
if (null != socket && !socket.isClosed()) {
socket.close();
} else {
networkSystem.socketClose(fd);
}
| protected void | implConfigureBlocking(boolean blockingMode)
// Do nothing here. For real read/write operation in nonblocking mode,
// it uses select system call. Whether a channel is blocking can be
// decided by isBlocking() method.
| public synchronized boolean | isConnected()
return connected;
| public int | read(java.nio.ByteBuffer target)
if (null == target) {
throw new NullPointerException();
}
// status must be open and connected
checkOpenConnected();
// target buffer must be not null and not readonly
checkWritable(target);
if (!target.hasRemaining()) {
return 0;
}
int readCount = 0;
if (target.isDirect() || target.hasArray()) {
readCount = readImpl(target);
if(readCount > 0){
target.position(target.position() + readCount);
}
} else {
byte[] readArray = new byte[target.remaining()];
ByteBuffer readBuffer = ByteBuffer.wrap(readArray);
readCount = readImpl(readBuffer);
if(readCount > 0){
target.put(readArray, 0, readCount);
}
}
return readCount;
| public long | read(java.nio.ByteBuffer[] targets, int offset, int length)
if (length < 0 || offset < 0
|| (long) length + (long) offset > targets.length) {
throw new IndexOutOfBoundsException();
}
// status must be open and connected
checkOpenConnected();
int totalCount = 0;
for (int val = offset; val < length; val++) {
// target buffer must be not null and not readonly
checkWritable(targets[val]);
totalCount += targets[val].remaining();
}
// read data to readBuffer, and then transfer data from readBuffer to
// targets.
ByteBuffer readBuffer = ByteBuffer.allocate(totalCount);
int readCount;
readCount = readImpl(readBuffer);
int left = readCount;
int index = offset;
// transfer data from readBuffer to targets
byte[] readArray = readBuffer.array();
while (left > 0) {
int putLength = Math.min(targets[index].remaining(), left);
targets[index].put(readArray, readCount - left, putLength);
index++;
left -= putLength;
}
return readCount;
| private int | readImpl(java.nio.ByteBuffer readBuffer)
synchronized(readLock){
int readCount = 0;
try {
begin();
// timeout == 0 means block read.
// DEFAULT_TIMEOUT is used in non-block mode.
int timeout = isBlocking() ? 0 : DEFAULT_TIMEOUT;
int start = readBuffer.position();
int length = readBuffer.remaining();
if (readBuffer.isDirect()) {
int address = AddressUtil.getDirectBufferAddress(readBuffer);
if (isConnected()) {
readCount = networkSystem.recvConnectedDatagramDirect(fd,
null, address, start, length, timeout, false);
} else {
readCount = networkSystem.receiveDatagramDirect(fd,
null, address, start, length, timeout, false);
}
} else {
// the target is assured to have array.
byte[] target = readBuffer.array();
start += readBuffer.arrayOffset();
if (isConnected()) {
readCount = networkSystem.recvConnectedDatagram(fd, null,
target, start, length, timeout, false);
} else {
readCount = networkSystem.receiveDatagram(fd, null, target,
start, length, timeout, false);
}
}
return readCount;
} catch (InterruptedIOException e) {
// InterruptedIOException will be thrown when timeout.
return 0;
} finally {
end(readCount > 0);
}
}
| public java.net.SocketAddress | receive(java.nio.ByteBuffer target)
// must not null and not readonly
checkWritable(target);
// must open
checkOpen();
if (!isBound) {
return null;
}
SocketAddress retAddr = null;
try {
begin();
// receive real data packet, (not peek)
synchronized (readLock) {
boolean loop = isBlocking();
if (!target.isDirect()) {
retAddr = receiveImpl(target, loop);
} else {
retAddr = receiveDirectImpl(target, loop);
}
}
} catch (InterruptedIOException e) {
// this line used in Linux
return null;
} finally {
end(null != retAddr);
}
return retAddr;
| private java.net.SocketAddress | receiveDirectImpl(java.nio.ByteBuffer target, boolean loop)
SocketAddress retAddr = null;
DatagramPacket receivePacket = new DatagramPacket(
stubArray, 0);
int oldposition = target.position();
int received = 0;
do {
int address = AddressUtil.getDirectBufferAddress(target);
if (isConnected()) {
received = networkSystem.recvConnectedDatagramDirect(fd, receivePacket,
address, target.position(),
target.remaining(), isBlocking() ? 0
: DEFAULT_TIMEOUT, false);
} else {
received = networkSystem.receiveDatagramDirect(fd, receivePacket,
address, target.position(),
target.remaining(), isBlocking() ? 0
: DEFAULT_TIMEOUT, false);
}
// security check
SecurityManager sm = System.getSecurityManager();
if (!isConnected() && null != sm) {
try {
sm.checkAccept(receivePacket.getAddress()
.getHostAddress(), receivePacket.getPort());
} catch (SecurityException e) {
// do discard the datagram packet
receivePacket = null;
}
}
if (null != receivePacket
&& null != receivePacket.getAddress()) {
// copy the data of received packet
if (received > 0) {
target.position(oldposition + received);
}
retAddr = receivePacket.getSocketAddress();
break;
}
} while (loop);
return retAddr;
| private java.net.SocketAddress | receiveImpl(java.nio.ByteBuffer target, boolean loop)
SocketAddress retAddr = null;
DatagramPacket receivePacket;
int oldposition = target.position();
int received = 0;
if (target.hasArray()) {
receivePacket = new DatagramPacket(target.array(), target
.position()
+ target.arrayOffset(), target.remaining());
} else {
receivePacket = new DatagramPacket(new byte[target.remaining()], target.remaining());
}
do {
if (isConnected()) {
received = networkSystem.recvConnectedDatagram(fd, receivePacket,
receivePacket.getData(), receivePacket.getOffset(),
receivePacket.getLength(), isBlocking() ? 0
: DEFAULT_TIMEOUT, false);
} else {
received = networkSystem.receiveDatagram(fd, receivePacket,
receivePacket.getData(), receivePacket.getOffset(),
receivePacket.getLength(), isBlocking() ? 0
: DEFAULT_TIMEOUT, false);
}
// security check
SecurityManager sm = System.getSecurityManager();
if (!isConnected() && null != sm) {
try {
sm.checkAccept(receivePacket.getAddress().getHostAddress(),
receivePacket.getPort());
} catch (SecurityException e) {
// do discard the datagram packet
receivePacket = null;
}
}
if (null != receivePacket && null != receivePacket.getAddress()) {
if (received > 0) {
if (target.hasArray()) {
target.position(oldposition + received);
} else {
// copy the data of received packet
target.put(receivePacket.getData(), 0, received);
}
}
retAddr = receivePacket.getSocketAddress();
break;
}
} while (loop);
return retAddr;
| public int | send(java.nio.ByteBuffer source, java.net.SocketAddress socketAddress)
// must not null
checkNotNull(source);
// must open
checkOpen();
// transfer socketAddress
InetSocketAddress isa = (InetSocketAddress) socketAddress;
if (null == isa.getAddress()) {
throw new IOException();
}
if (isConnected()) {
if (!connectAddress.equals(isa)) {
throw new IllegalArgumentException();
}
} else {
// not connected, check security
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
if (isa.getAddress().isMulticastAddress()) {
sm.checkMulticast(isa.getAddress());
} else {
sm.checkConnect(isa.getAddress().getHostAddress(), isa
.getPort());
}
}
}
// the return value.
int sendCount = 0;
try {
begin();
byte[] array = null;
int length = source.remaining();
int oldposition = source.position();
int start = oldposition;
if (source.isDirect()) {
synchronized (writeLock) {
int data_address = AddressUtil
.getDirectBufferAddress(source);
sendCount = networkSystem.sendDatagramDirect(fd,
data_address, start, length, isa.getPort(), false,
trafficClass, isa.getAddress());
}
} else {
if (source.hasArray()) {
array = source.array();
start += source.arrayOffset();
} else {
array = new byte[length];
source.get(array);
start = 0;
}
synchronized (writeLock) {
sendCount = networkSystem.sendDatagram(fd, array, start,
length, isa.getPort(), false, trafficClass, isa
.getAddress());
}
}
source.position(oldposition + sendCount);
return sendCount;
} finally {
end(sendCount >= 0);
}
| public synchronized java.net.DatagramSocket | socket()
if (null == socket) {
socket = new DatagramSocketAdapter(SocketImplProvider
.getDatagramSocketImpl(fd, localPort), this);
}
return socket;
| public int | write(java.nio.ByteBuffer source)
// source buffer must be not null
checkNotNull(source);
// status must be open and connected
checkOpenConnected();
// return immediately if source is full
if (!source.hasRemaining()) {
return 0;
}
ByteBuffer writeBuffer = null;
byte[] writeArray = null;
int oldposition = source.position();
int result;
if (source.isDirect() || source.hasArray()) {
writeBuffer = source;
} else {
writeArray = new byte[source.remaining()];
source.get(writeArray);
writeBuffer = ByteBuffer.wrap(writeArray);
}
result = writeImpl(writeBuffer);
if (result > 0) {
source.position(oldposition + result);
}
return result;
| public long | write(java.nio.ByteBuffer[] sources, int offset, int length)
if (length < 0 || offset < 0
|| (long) length + (long) offset > sources.length) {
throw new IndexOutOfBoundsException();
}
// status must be open and connected
checkOpenConnected();
int count = calculateByteBufferArray(sources, offset, length);
if (0 == count) {
return 0;
}
ByteBuffer writeBuf = ByteBuffer.allocate(count);
for (int val = offset; val < length+offset; val++) {
ByteBuffer source = sources[val];
int oldPosition = source.position();
writeBuf.put(source);
source.position(oldPosition);
}
writeBuf.flip();
int result = writeImpl(writeBuf);
int val = offset;
int written = result;
while (result > 0) {
ByteBuffer source = sources[val];
int gap = Math.min(result, source.remaining());
source.position(source.position() + gap);
val++;
result -= gap;
}
return written;
| private int | writeImpl(java.nio.ByteBuffer buf)
synchronized(writeLock){
int result = 0;
try {
begin();
int length = buf.remaining();
int start = buf.position();
if (buf.isDirect()) {
int address = AddressUtil.getDirectBufferAddress(buf);
result = networkSystem.sendConnectedDatagramDirect(fd, address,
start, length, isBound);
} else {
// buf is assured to have array.
start += buf.arrayOffset();
result = networkSystem.sendConnectedDatagram(fd, buf.array(),
start, length, isBound);
}
return result;
} catch (SocketException e) {
if (e.getCause() instanceof ErrorCodeException) {
if (ERRCODE_SOCKET_NONBLOCKING_WOULD_BLOCK == ((ErrorCodeException) e
.getCause()).getErrorCode()) {
return result;
}
}
throw e;
} finally {
end(result > 0);
}
}
|
|