use of java.nio.channels.ServerSocketChannel in project AndroidAsync by koush.
the class AsyncServer method runLoop.
private static void runLoop(final AsyncServer server, final SelectorWrapper selector, final PriorityQueue<Scheduled> queue) throws AsyncSelectorException {
// Log.i(LOGTAG, "Keys: " + selector.keys().size());
boolean needsSelect = true;
// run the queue to populate the selector with keys
long wait = lockAndRunQueue(server, queue);
try {
synchronized (server) {
// select now to see if anything is ready immediately. this
// also clears the canceled key queue.
int readyNow = selector.selectNow();
if (readyNow == 0) {
// which means it would be time to turn this thread off.
if (selector.keys().size() == 0 && wait == QUEUE_EMPTY) {
// Log.i(LOGTAG, "Shutting down. keys: " + selector.keys().size() + " keepRunning: " + keepRunning);
return;
}
} else {
needsSelect = false;
}
}
if (needsSelect) {
if (wait == QUEUE_EMPTY) {
// wait until woken up
selector.select();
} else {
// nothing to select immediately but there's something pending so let's block that duration and wait.
selector.select(wait);
}
}
} catch (Exception e) {
throw new AsyncSelectorException(e);
}
// process whatever keys are ready
Set<SelectionKey> readyKeys = selector.selectedKeys();
for (SelectionKey key : readyKeys) {
try {
if (key.isAcceptable()) {
ServerSocketChannel nextReady = (ServerSocketChannel) key.channel();
SocketChannel sc = null;
SelectionKey ckey = null;
try {
sc = nextReady.accept();
if (sc == null)
continue;
sc.configureBlocking(false);
ckey = sc.register(selector.getSelector(), SelectionKey.OP_READ);
ListenCallback serverHandler = (ListenCallback) key.attachment();
AsyncNetworkSocket handler = new AsyncNetworkSocket();
handler.attach(sc, (InetSocketAddress) sc.socket().getRemoteSocketAddress());
handler.setup(server, ckey);
ckey.attach(handler);
serverHandler.onAccepted(handler);
} catch (IOException e) {
StreamUtility.closeQuietly(sc);
if (ckey != null)
ckey.cancel();
}
} else if (key.isReadable()) {
AsyncNetworkSocket handler = (AsyncNetworkSocket) key.attachment();
int transmitted = handler.onReadable();
server.onDataReceived(transmitted);
} else if (key.isWritable()) {
AsyncNetworkSocket handler = (AsyncNetworkSocket) key.attachment();
handler.onDataWritable();
} else if (key.isConnectable()) {
ConnectFuture cancel = (ConnectFuture) key.attachment();
SocketChannel sc = (SocketChannel) key.channel();
key.interestOps(SelectionKey.OP_READ);
AsyncNetworkSocket newHandler;
try {
sc.finishConnect();
newHandler = new AsyncNetworkSocket();
newHandler.setup(server, key);
newHandler.attach(sc, (InetSocketAddress) sc.socket().getRemoteSocketAddress());
key.attach(newHandler);
} catch (IOException ex) {
key.cancel();
StreamUtility.closeQuietly(sc);
if (cancel.setComplete(ex))
cancel.callback.onConnectCompleted(ex, null);
continue;
}
try {
if (cancel.setComplete(newHandler))
cancel.callback.onConnectCompleted(null, newHandler);
} catch (Exception e) {
throw new RuntimeException(e);
}
} else {
Log.i(LOGTAG, "wtf");
throw new RuntimeException("Unknown key state.");
}
} catch (CancelledKeyException ex) {
}
}
readyKeys.clear();
}
use of java.nio.channels.ServerSocketChannel in project jetty.project by eclipse.
the class IOTest method testHalfCloseBadClient.
@Test
public void testHalfCloseBadClient() throws Exception {
ServerSocketChannel connector = ServerSocketChannel.open();
connector.socket().bind(null);
Socket client = SocketChannel.open(connector.socket().getLocalSocketAddress()).socket();
client.setSoTimeout(1000);
client.setSoLinger(false, -1);
Socket server = connector.accept().socket();
server.setSoTimeout(1000);
server.setSoLinger(false, -1);
// Write from client to server
client.getOutputStream().write(1);
// Server reads
assertEquals(1, server.getInputStream().read());
// Write from server to client with oshut
server.getOutputStream().write(1);
//System.err.println("OSHUT "+server);
server.shutdownOutput();
try {
// Client reads response
assertEquals(1, client.getInputStream().read());
// Client reads -1
assertEquals(-1, client.getInputStream().read());
assertFalse(client.isInputShutdown());
// Client can still write as we are half closed
client.getOutputStream().write(1);
// Server can still read
assertEquals(1, server.getInputStream().read());
// Server now closes
server.close();
// Client still reads -1 (not broken pipe !!)
assertEquals(-1, client.getInputStream().read());
assertFalse(client.isInputShutdown());
Thread.sleep(100);
// Client still reads -1 (not broken pipe !!)
assertEquals(-1, client.getInputStream().read());
assertFalse(client.isInputShutdown());
// Client can still write data even though server is closed???
client.getOutputStream().write(1);
// Client eventually sees Broken Pipe
int i = 0;
try {
for (i = 0; i < 100000; i++) client.getOutputStream().write(1);
Assert.fail();
} catch (IOException e) {
}
client.close();
} catch (Exception e) {
System.err.println("PLEASE INVESTIGATE:");
e.printStackTrace();
}
}
use of java.nio.channels.ServerSocketChannel in project jetty.project by eclipse.
the class IOTest method testServerChannelInterrupt.
@Test
public void testServerChannelInterrupt() throws Exception {
final ServerSocketChannel connector = ServerSocketChannel.open();
connector.configureBlocking(true);
connector.socket().bind(null);
Socket client = SocketChannel.open(connector.socket().getLocalSocketAddress()).socket();
client.setSoTimeout(2000);
client.setSoLinger(false, -1);
Socket server = connector.accept().socket();
server.setSoTimeout(2000);
server.setSoLinger(false, -1);
// Write from client to server
client.getOutputStream().write(1);
// Server reads
assertEquals(1, server.getInputStream().read());
// Write from server to client
server.getOutputStream().write(1);
// Client reads
assertEquals(1, client.getInputStream().read());
// block a thread in accept
final CountDownLatch alatch = new CountDownLatch(2);
Thread acceptor = new Thread() {
@Override
public void run() {
try {
alatch.countDown();
connector.accept();
} catch (Throwable e) {
} finally {
alatch.countDown();
}
}
};
acceptor.start();
while (alatch.getCount() == 2) Thread.sleep(10);
// interrupt the acceptor
acceptor.interrupt();
// wait for acceptor to exit
assertTrue(alatch.await(10, TimeUnit.SECONDS));
// connector is closed
assertFalse(connector.isOpen());
// but connection is still open
assertFalse(client.isClosed());
assertFalse(server.isClosed());
// Write from client to server
client.getOutputStream().write(42);
// Server reads
assertEquals(42, server.getInputStream().read());
// Write from server to client
server.getOutputStream().write(43);
// Client reads
assertEquals(43, client.getInputStream().read());
client.close();
}
use of java.nio.channels.ServerSocketChannel in project jetty.project by eclipse.
the class SelectorManagerTest method testConnectTimeoutBeforeSuccessfulConnect.
@Slow
@Test
public void testConnectTimeoutBeforeSuccessfulConnect() throws Exception {
ServerSocketChannel server = ServerSocketChannel.open();
server.bind(new InetSocketAddress("localhost", 0));
SocketAddress address = server.getLocalAddress();
final AtomicLong timeoutConnection = new AtomicLong();
final long connectTimeout = 1000;
SelectorManager selectorManager = new SelectorManager(executor, scheduler) {
@Override
protected EndPoint newEndPoint(SelectableChannel channel, ManagedSelector selector, SelectionKey key) throws IOException {
SocketChannelEndPoint endp = new SocketChannelEndPoint(channel, selector, key, getScheduler());
endp.setIdleTimeout(connectTimeout / 2);
return endp;
}
@Override
protected boolean doFinishConnect(SelectableChannel channel) throws IOException {
try {
long timeout = timeoutConnection.get();
if (timeout > 0)
TimeUnit.MILLISECONDS.sleep(timeout);
return super.doFinishConnect(channel);
} catch (InterruptedException e) {
return false;
}
}
@Override
public Connection newConnection(SelectableChannel channel, EndPoint endpoint, Object attachment) throws IOException {
((Callback) attachment).succeeded();
return new AbstractConnection(endpoint, executor) {
@Override
public void onFillable() {
}
};
}
@Override
protected void connectionFailed(SelectableChannel channel, Throwable ex, Object attachment) {
((Callback) attachment).failed(ex);
}
};
selectorManager.setConnectTimeout(connectTimeout);
selectorManager.start();
try {
SocketChannel client1 = SocketChannel.open();
client1.configureBlocking(false);
client1.connect(address);
long timeout = connectTimeout * 2;
timeoutConnection.set(timeout);
final CountDownLatch latch1 = new CountDownLatch(1);
selectorManager.connect(client1, new Callback() {
@Override
public void failed(Throwable x) {
latch1.countDown();
}
});
Assert.assertTrue(latch1.await(connectTimeout * 3, TimeUnit.MILLISECONDS));
Assert.assertFalse(client1.isOpen());
// Wait for the first connect to finish, as the selector thread is waiting in finishConnect().
Thread.sleep(timeout);
// Verify that after the failure we can connect successfully.
try (SocketChannel client2 = SocketChannel.open()) {
client2.configureBlocking(false);
client2.connect(address);
timeoutConnection.set(0);
final CountDownLatch latch2 = new CountDownLatch(1);
selectorManager.connect(client2, new Callback() {
@Override
public void succeeded() {
latch2.countDown();
}
});
Assert.assertTrue(latch2.await(connectTimeout * 5, TimeUnit.MILLISECONDS));
Assert.assertTrue(client2.isOpen());
}
} finally {
selectorManager.stop();
}
}
use of java.nio.channels.ServerSocketChannel in project jetty.project by eclipse.
the class ServerConnector method open.
@Override
public void open() throws IOException {
if (_acceptChannel == null) {
ServerSocketChannel serverChannel = null;
if (isInheritChannel()) {
Channel channel = System.inheritedChannel();
if (channel instanceof ServerSocketChannel)
serverChannel = (ServerSocketChannel) channel;
else
LOG.warn("Unable to use System.inheritedChannel() [{}]. Trying a new ServerSocketChannel at {}:{}", channel, getHost(), getPort());
}
if (serverChannel == null) {
serverChannel = ServerSocketChannel.open();
InetSocketAddress bindAddress = getHost() == null ? new InetSocketAddress(getPort()) : new InetSocketAddress(getHost(), getPort());
serverChannel.socket().setReuseAddress(getReuseAddress());
serverChannel.socket().bind(bindAddress, getAcceptQueueSize());
_localPort = serverChannel.socket().getLocalPort();
if (_localPort <= 0)
throw new IOException("Server channel not bound");
}
serverChannel.configureBlocking(true);
addBean(serverChannel);
_acceptChannel = serverChannel;
}
}
Aggregations