use of java.nio.channels.DatagramChannel in project tomcat70 by apache.
the class NioReplicationTask method sendAck.
/**
* send a reply-acknowledgement (6,2,3), sends it doing a busy write, the ACK is so small
* that it should always go to the buffer
* @param key
* @param channel
*/
protected void sendAck(SelectionKey key, WritableByteChannel channel, byte[] command, SocketAddress udpaddr) {
try {
ByteBuffer buf = ByteBuffer.wrap(command);
int total = 0;
if (channel instanceof DatagramChannel) {
DatagramChannel dchannel = (DatagramChannel) channel;
// TODO check optimization, one channel per thread?
while (total < command.length) {
total += dchannel.send(buf, udpaddr);
}
} else {
while (total < command.length) {
total += channel.write(buf);
}
}
if (log.isTraceEnabled()) {
log.trace("ACK sent to " + ((channel instanceof SocketChannel) ? ((SocketChannel) channel).socket().getInetAddress() : ((DatagramChannel) channel).socket().getInetAddress()));
}
} catch (java.io.IOException x) {
log.warn("Unable to send ACK back through channel, channel disconnected?: " + x.getMessage());
}
}
use of java.nio.channels.DatagramChannel in project tomcat70 by apache.
the class NioReplicationTask method drainChannel.
/**
* The actual code which drains the channel associated with
* the given key. This method assumes the key has been
* modified prior to invocation to turn off selection
* interest in OP_READ. When this method completes it
* re-enables OP_READ and calls wakeup() on the selector
* so the selector will resume watching this channel.
*/
protected void drainChannel(final SelectionKey key, ObjectReader reader) throws Exception {
reader.setLastAccess(System.currentTimeMillis());
reader.access();
ReadableByteChannel channel = (ReadableByteChannel) key.channel();
int count = -1;
// make buffer empty
buffer.clear();
SocketAddress saddr = null;
if (channel instanceof SocketChannel) {
// loop while data available, channel is non-blocking
while ((count = channel.read(buffer)) > 0) {
// make buffer readable
buffer.flip();
if (buffer.hasArray())
reader.append(buffer.array(), 0, count, false);
else
reader.append(buffer, count, false);
// make buffer empty
buffer.clear();
// do we have at least one package?
if (reader.hasPackage())
break;
}
} else if (channel instanceof DatagramChannel) {
DatagramChannel dchannel = (DatagramChannel) channel;
saddr = dchannel.receive(buffer);
// make buffer readable
buffer.flip();
if (buffer.hasArray())
reader.append(buffer.array(), 0, buffer.limit() - buffer.position(), false);
else
reader.append(buffer, buffer.limit() - buffer.position(), false);
// make buffer empty
buffer.clear();
// did we get a package
count = reader.hasPackage() ? 1 : -1;
}
int pkgcnt = reader.count();
if (count < 0 && pkgcnt == 0) {
// end of stream, and no more packages to process
remoteEof(key);
return;
}
ChannelMessage[] msgs = pkgcnt == 0 ? ChannelData.EMPTY_DATA_ARRAY : reader.execute();
// register to read new data, before we send it off to avoid dead locks
registerForRead(key, reader);
for (int i = 0; i < msgs.length; i++) {
/**
* Use send ack here if you want to ack the request to the remote
* server before completing the request
* This is considered an asynchronous request
*/
if (ChannelData.sendAckAsync(msgs[i].getOptions()))
sendAck(key, (WritableByteChannel) channel, Constants.ACK_COMMAND, saddr);
try {
if (Logs.MESSAGES.isTraceEnabled()) {
try {
Logs.MESSAGES.trace("NioReplicationThread - Received msg:" + new UniqueId(msgs[i].getUniqueId()) + " at " + new java.sql.Timestamp(System.currentTimeMillis()));
} catch (Throwable t) {
}
}
// process the message
getCallback().messageDataReceived(msgs[i]);
/**
* Use send ack here if you want the request to complete on this
* server before sending the ack to the remote server
* This is considered a synchronized request
*/
if (ChannelData.sendAckSync(msgs[i].getOptions()))
sendAck(key, (WritableByteChannel) channel, Constants.ACK_COMMAND, saddr);
} catch (RemoteProcessException e) {
if (log.isDebugEnabled())
log.error("Processing of cluster message failed.", e);
if (ChannelData.sendAckSync(msgs[i].getOptions()))
sendAck(key, (WritableByteChannel) channel, Constants.FAIL_ACK_COMMAND, saddr);
} catch (Exception e) {
log.error("Processing of cluster message failed.", e);
if (ChannelData.sendAckSync(msgs[i].getOptions()))
sendAck(key, (WritableByteChannel) channel, Constants.FAIL_ACK_COMMAND, saddr);
}
if (getUseBufferPool()) {
BufferPool.getBufferPool().returnBuffer(msgs[i].getMessage());
msgs[i].setMessage(null);
}
}
if (count < 0) {
remoteEof(key);
return;
}
}
use of java.nio.channels.DatagramChannel in project tomcat70 by apache.
the class NioReplicationTask method run.
// loop forever waiting for work to do
@Override
public synchronized void run() {
if (buffer == null) {
int size = getRxBufSize();
if (key.channel() instanceof DatagramChannel) {
size = ChannelReceiver.MAX_UDP_SIZE;
}
if ((getOptions() & OPTION_DIRECT_BUFFER) == OPTION_DIRECT_BUFFER) {
buffer = ByteBuffer.allocateDirect(size);
} else {
buffer = ByteBuffer.allocate(size);
}
} else {
buffer.clear();
}
if (key == null) {
// just in case
return;
}
if (log.isTraceEnabled())
log.trace("Servicing key:" + key);
try {
ObjectReader reader = (ObjectReader) key.attachment();
if (reader == null) {
if (log.isTraceEnabled())
log.trace("No object reader, cancelling:" + key);
cancelKey(key);
} else {
if (log.isTraceEnabled())
log.trace("Draining channel:" + key);
drainChannel(key, reader);
}
} catch (Exception e) {
// end expire after a certain time.
if (e instanceof CancelledKeyException) {
// do nothing
} else if (e instanceof IOException) {
// dont spew out stack traces for IO exceptions unless debug is enabled.
if (log.isDebugEnabled())
log.debug("IOException in replication worker, unable to drain channel. Probable cause: Keep alive socket closed[" + e.getMessage() + "].", e);
else
log.warn("IOException in replication worker, unable to drain channel. Probable cause: Keep alive socket closed[" + e.getMessage() + "].");
} else if (log.isErrorEnabled()) {
// this is a real error, log it.
log.error("Exception caught in TcpReplicationThread.drainChannel.", e);
}
cancelKey(key);
} finally {
}
key = null;
// done, ready for more, return to pool
getTaskPool().returnWorker(this);
}
use of java.nio.channels.DatagramChannel in project AndroidAsync by koush.
the class AsyncServer method openDatagram.
public AsyncDatagramSocket openDatagram(final InetAddress host, final int port, final boolean reuseAddress) {
final AsyncDatagramSocket handler = new AsyncDatagramSocket();
// ugh.. this should really be post to make it nonblocking...
// but i want datagrams to be immediately writable.
// they're not really used anyways.
Runnable runnable = () -> {
final DatagramChannel socket;
try {
socket = DatagramChannel.open();
} catch (Exception e) {
return;
}
try {
handler.attach(socket);
InetSocketAddress address;
if (host == null)
address = new InetSocketAddress(port);
else
address = new InetSocketAddress(host, port);
if (reuseAddress)
socket.socket().setReuseAddress(reuseAddress);
socket.socket().bind(address);
handleSocket(handler);
} catch (IOException e) {
Log.e(LOGTAG, "Datagram error", e);
StreamUtility.closeQuietly(socket);
}
};
if (getAffinity() != Thread.currentThread()) {
run(runnable);
return handler;
}
runnable.run();
return handler;
}
use of java.nio.channels.DatagramChannel in project AndroidAsync by koush.
the class AsyncServer method createDatagram.
private Cancellable createDatagram(ValueFunction<InetAddress> inetAddressValueFunction, final int port, final boolean reuseAddress, FutureCallback<AsyncDatagramSocket> callback) {
SimpleFuture<AsyncDatagramSocket> ret = new SimpleFuture<>();
ret.setCallback(callback);
post(() -> {
DatagramChannel socket = null;
try {
socket = DatagramChannel.open();
final AsyncDatagramSocket handler = new AsyncDatagramSocket();
handler.attach(socket);
InetSocketAddress address;
if (inetAddressValueFunction == null)
address = new InetSocketAddress(port);
else
address = new InetSocketAddress(inetAddressValueFunction.getValue(), port);
if (reuseAddress)
socket.socket().setReuseAddress(reuseAddress);
socket.socket().bind(address);
handleSocket(handler);
if (!ret.setComplete(handler))
socket.close();
} catch (Exception e) {
StreamUtility.closeQuietly(socket);
ret.setComplete(e);
}
});
return ret;
}
Aggregations