/** MemcachedClient calls this method to handle IO over the connections. */ @SuppressWarnings("unchecked") public void handleIO() throws IOException { if (shutDown) { throw new IOException("No IO while shut down"); } // Deal with all of the stuff that's been added, but may not be marked // writable. handleInputQueue(); getLogger().debug("Done dealing with queue."); long delay = 0; if (!reconnectQueue.isEmpty()) { long now = System.currentTimeMillis(); long then = reconnectQueue.firstKey(); delay = Math.max(then - now, 1); } getLogger().debug("Selecting with delay of %sms", delay); assert selectorsMakeSense() : "Selectors don't make sense."; int selected = selector.select(delay); Set<SelectionKey> selectedKeys = selector.selectedKeys(); if (selectedKeys.isEmpty() && !shutDown) { getLogger().debug("No selectors ready, interrupted: " + Thread.interrupted()); if (++emptySelects > DOUBLE_CHECK_EMPTY) { for (SelectionKey sk : selector.keys()) { getLogger().info("%s has %s, interested in %s", sk, sk.readyOps(), sk.interestOps()); if (sk.readyOps() != 0) { getLogger().info("%s has a ready op, handling IO", sk); handleIO(sk); } else { queueReconnect((MemcachedNode) sk.attachment()); } } assert emptySelects < EXCESSIVE_EMPTY : "Too many empty selects"; } } else { getLogger().debug("Selected %d, selected %d keys", selected, selectedKeys.size()); emptySelects = 0; for (SelectionKey sk : selectedKeys) { handleIO(sk); } // for each selector selectedKeys.clear(); } if (!shutDown && !reconnectQueue.isEmpty()) { attemptReconnects(); } }
/** * Serves the incoming connections. * * @throws IOException * @throws DirectoryException */ private void serveIncomingConnections() throws IOException, DirectoryException { int selectorState = selector.select(); // We can't rely on return value of select to determine if any keys // are ready. // see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4850373 for (Iterator<SelectionKey> iterator = selector.selectedKeys().iterator(); iterator.hasNext(); ) { SelectionKey key = iterator.next(); iterator.remove(); if (key.isAcceptable()) { // Accept the new client connection. ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel(); SocketChannel clientChannel = serverChannel.accept(); if (clientChannel != null) { acceptConnection(clientChannel); } } if (selectorState == 0 && enabled && !shutdownRequested && logger.isTraceEnabled()) { // Selected keys was non empty but select() returned 0. // Log warning and hope it blocks on the next select() call. logger.trace( "Selector.select() returned 0. " + "Selected Keys: %d, Interest Ops: %d, Ready Ops: %d ", selector.selectedKeys().size(), key.interestOps(), key.readyOps()); } } }
@Override public void run() { final Selector selector = this.selector; for (; ; ) { ++reactCount; try { selector.select(1000L); register(selector); Set<SelectionKey> keys = selector.selectedKeys(); try { for (SelectionKey key : keys) { Object att = key.attachment(); System.out.println("attchment " + att); if (att != null && key.isValid()) { int readyOps = key.readyOps(); if ((readyOps & SelectionKey.OP_READ) != 0) { read((NIOConnection) att); } else if ((readyOps & SelectionKey.OP_WRITE) != 0) { write((NIOConnection) att); } else { key.cancel(); } } else { key.cancel(); } } } finally { keys.clear(); } } catch (Throwable e) { LOGGER.warn(name, e); } } }
@Override public void run() { try { selector = Selector.open(); while (true) { processSelectionQueue(); int nKeys = selector.select(selectWaitTime); // blocking if (nKeys == 0) { continue; } else { logger.trace(String.format("Selector %d, keys num: %d", selectorNum, nKeys)); } Set<SelectionKey> keys = selector.selectedKeys(); Iterator<SelectionKey> iter = keys.iterator(); while (iter.hasNext()) { SelectionKey key = iter.next(); iter.remove(); logger.trace("Key operations: " + key.readyOps()); if (key.isWritable()) { doWrite(key); } } } } catch (IOException e) { throw new RuntimeException(e); } }
public void run() { System.out.println("Server started ..."); System.out.println("Server listening on port: " + port); // 监听 while (true) { try { int num = 0; num = selector.select(); if (num > 0) { Set selectedKeys = selector.selectedKeys(); Iterator it = selectedKeys.iterator(); while (it.hasNext()) { SelectionKey key = (SelectionKey) it.next(); it.remove(); // 处理IO事件 if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) { // Accept the new connection ServerSocketChannel ssc = (ServerSocketChannel) key.channel(); notifier.fireOnAccept(); SocketChannel sc = ssc.accept(); sc.configureBlocking(false); // 触发接受连接事件 Request request = new Request(sc); notifier.fireOnAccepted(request); // 注册读操作,以进行下一步的读操作 sc.register(selector, SelectionKey.OP_READ, request); } else if ((key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) { Reader.processRequest(key); // 提交读服务线程读取客户端数据 key.cancel(); } else if ((key.readyOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE) { Writer.processRequest(key); // 提交写服务线程向客户端发送回应数据 key.cancel(); } } } else { addRegister(); // 在Selector中注册新的写通道 } } catch (Exception e) { notifier.fireOnError("Error occured in Server: " + e.getMessage()); continue; } } }
// Remove connect interest from connected sockets // See: // http://stackoverflow.com/questions/204186/java-nio-select-returns-without-selected-keys-why private void processKey(SelectionKey key) { if ((key.readyOps() & SelectionKey.OP_CONNECT) != 0) { int interestOps = key.interestOps(); interestOps &= ~SelectionKey.OP_CONNECT; interestOps |= SelectionKey.OP_WRITE; key.interestOps(interestOps); } }
public void blockUntilReady(final int operationCode) throws IOException { key.interestOps(operationCode); int retryCount = 0; try { while (!((key.readyOps() & operationCode) != 0) && retryCount < numberOfRetries) { block(); retryCount++; } } finally { resetKey(); } }
@Override public void run() { try { while (isWork) { if (selector == null) { logger.trace("Selector is still null, stack is waiting for binding..."); Thread.sleep(250); continue; } // without timeout when we kill socket, this causes errors, bug in VM ? int num = selector.select(100); if (num == 0) { continue; } Set<SelectionKey> keys = selector.selectedKeys(); try { for (SelectionKey key : keys) { if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) { try { Socket s = serverSocket.accept(); logger.info("Open incomming connection {}", s); TCPClientConnection client = new TCPClientConnection(null, concurrentFactory, s, parser, null); // PCB added logging logger.debug("Finished initialising TCPClientConnection for {}", s); for (INetworkConnectionListener listener : listeners) { listener.newNetworkConnection(client); } } catch (Exception e) { logger.warn("Can not create incoming connection", e); } } } } catch (Exception e) { logger.debug("Failed to accept connection,", e); } finally { keys.clear(); } } } catch (Exception exc) { logger.warn("Server socket stopped", exc); } }
protected void processKey(SelectionKey sk, NioSocketWrapper attachment) { try { if (close) { cancelledKey(sk); } else if (sk.isValid() && attachment != null) { if (sk.isReadable() || sk.isWritable()) { if (attachment.getSendfileData() != null) { processSendfile(sk, attachment, false); } else { unreg(sk, attachment, sk.readyOps()); boolean closeSocket = false; // Read goes before write if (sk.isReadable()) { if (!processSocket(attachment, SocketEvent.OPEN_READ, true)) { closeSocket = true; } } if (!closeSocket && sk.isWritable()) { if (!processSocket(attachment, SocketEvent.OPEN_WRITE, true)) { closeSocket = true; } } if (closeSocket) { cancelledKey(sk); } } } } else { // invalid key cancelledKey(sk); } } catch (CancelledKeyException ckx) { cancelledKey(sk); } catch (Throwable t) { ExceptionUtils.handleThrowable(t); log.error("", t); } }
private void processSelectedKeys(final Set<SelectionKey> selectedKeys) throws IOException { for (Iterator<SelectionKey> i = selectedKeys.iterator(); i.hasNext(); ) { SelectionKey k = i.next(); i.remove(); try { int readyOps = k.readyOps(); if ((readyOps & SelectionKey.OP_READ) != 0 || readyOps == 0) { if (!read(k)) { // Connection already closed - no need to handle write. continue; } } if ((readyOps & SelectionKey.OP_WRITE) != 0) { writeFromSelectorLoop(k); } } catch (CancelledKeyException e) { close(k); } if (cleanUpCancelledKeys()) { break; // break the loop to avoid ConcurrentModificationException } } }
public SendfileState processSendfile( SelectionKey sk, NioSocketWrapper socketWrapper, boolean calledByProcessor) { NioChannel sc = null; try { unreg(sk, socketWrapper, sk.readyOps()); SendfileData sd = socketWrapper.getSendfileData(); if (log.isTraceEnabled()) { log.trace("Processing send file for: " + sd.fileName); } if (sd.fchannel == null) { // Setup the file channel File f = new File(sd.fileName); if (!f.exists()) { cancelledKey(sk); return SendfileState.ERROR; } @SuppressWarnings("resource") // Closed when channel is closed FileInputStream fis = new FileInputStream(f); sd.fchannel = fis.getChannel(); } // Configure output channel sc = socketWrapper.getSocket(); // TLS/SSL channel is slightly different WritableByteChannel wc = ((sc instanceof SecureNioChannel) ? sc : sc.getIOChannel()); // We still have data in the buffer if (sc.getOutboundRemaining() > 0) { if (sc.flushOutbound()) { socketWrapper.updateLastWrite(); } } else { long written = sd.fchannel.transferTo(sd.pos, sd.length, wc); if (written > 0) { sd.pos += written; sd.length -= written; socketWrapper.updateLastWrite(); } else { // Unusual not to be able to transfer any bytes // Check the length was set correctly if (sd.fchannel.size() <= sd.pos) { throw new IOException( "Sendfile configured to " + "send more data than was available"); } } } if (sd.length <= 0 && sc.getOutboundRemaining() <= 0) { if (log.isDebugEnabled()) { log.debug("Send file complete for: " + sd.fileName); } socketWrapper.setSendfileData(null); try { sd.fchannel.close(); } catch (Exception ignore) { } // For calls from outside the Poller, the caller is // responsible for registering the socket for the // appropriate event(s) if sendfile completes. if (!calledByProcessor) { if (sd.keepAlive) { if (log.isDebugEnabled()) { log.debug("Connection is keep alive, registering back for OP_READ"); } reg(sk, socketWrapper, SelectionKey.OP_READ); } else { if (log.isDebugEnabled()) { log.debug("Send file connection is being closed"); } close(sc, sk); } } return SendfileState.DONE; } else { if (log.isDebugEnabled()) { log.debug("OP_WRITE for sendfile: " + sd.fileName); } if (calledByProcessor) { add(socketWrapper.getSocket(), SelectionKey.OP_WRITE); } else { reg(sk, socketWrapper, SelectionKey.OP_WRITE); } return SendfileState.PENDING; } } catch (IOException x) { if (log.isDebugEnabled()) log.debug("Unable to complete sendfile request:", x); if (!calledByProcessor && sc != null) { close(sc, sk); } else { cancelledKey(sk); } return SendfileState.ERROR; } catch (Throwable t) { log.error("", t); if (!calledByProcessor && sc != null) { close(sc, sk); } else { cancelledKey(sk); } return SendfileState.ERROR; } }
/** * logic performed on the selected keys * * @param readyKeys * @param selectorHandler * @param serverCtx */ private void handleSelectedKeys( Set<SelectionKey> readyKeys, SelectorHandler selectorHandler, NIOContext serverCtx) { for (SelectionKey key : readyKeys) { try { if (!key.isValid()) { selectorHandler.getSelectionKeyHandler().close(key); continue; } final int readyOps = key.readyOps(); if ((readyOps & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) { if (readThreadsCount > 0 && multiReadThreadSelectorHandler.supportsProtocol(selectorHandler.protocol())) { if (logger.isLoggable(Level.FINE)) { logger.log( Level.FINE, "OP_ACCEPT on " + key + " passed to multi readthread handler. Attachment: " + key.attachment()); } multiReadThreadSelectorHandler.onAcceptInterest(key, serverCtx); } else { if (logger.isLoggable(Level.FINE)) { logger.log(Level.FINE, "OP_ACCEPT on " + key + " attachment: " + key.attachment()); } selectorHandler.onAcceptInterest(key, serverCtx); } continue; } if ((readyOps & SelectionKey.OP_CONNECT) == SelectionKey.OP_CONNECT) { if (logger.isLoggable(Level.FINE)) { logger.log(Level.FINE, "OP_CONNECT on " + key + " attachment: " + key.attachment()); } selectorHandler.onConnectInterest(key, serverCtx); continue; } boolean delegateToWorker = false; OpType opType = null; boolean skipOpWrite = false; // OP_READ will always be processed first, then // based on the handleReadWriteConcurrently, the OP_WRITE // might be processed just after or during the next // Selector.select() invocation. if ((readyOps & SelectionKey.OP_READ) == SelectionKey.OP_READ) { if (logger.isLoggable(Level.FINE)) { logger.log(Level.FINE, "OP_READ on " + key + " attachment: " + key.attachment()); } delegateToWorker = selectorHandler.onReadInterest(key, serverCtx); if (delegateToWorker) { opType = OpType.OP_READ; } if (!handleReadWriteConcurrently) { skipOpWrite = true; } } // The OP_READ processing might have closed the // Selection, hence we must make sure the // SelectionKey is still valid. if (!skipOpWrite && key.isValid() && (readyOps & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE) { if (logger.isLoggable(Level.FINE)) { logger.log(Level.FINE, "OP_WRITE on " + key + " attachment: " + key.attachment()); } boolean opWriteDelegate = selectorHandler.onWriteInterest(key, serverCtx); delegateToWorker |= opWriteDelegate; if (opWriteDelegate) { if (opType == OpType.OP_READ) { opType = OpType.OP_READ_WRITE; } else { opType = OpType.OP_WRITE; } } } if (delegateToWorker) { NIOContext context = pollContext(key, opType); configureContext(context, selectorHandler); context.execute(ProtocolChainContextTask.poll()); } } catch (Throwable e) { handleSelectException(e, selectorHandler, key); } } }
public static void checkClients(List<SocketChannel> anonymousClients) { try { if (selector.selectNow() == 0) { return; } Set<SelectionKey> keys = selector.selectedKeys(); for (SelectionKey key : keys) { if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) { SocketChannel clientSocket = serverSocket.accept(); if (clientSocket == null) { System.err.println("Error: can not accept"); continue; } anonymousClients.add(clientSocket); clientSocket.configureBlocking(false); clientSocket.register(selector, SelectionKey.OP_READ); } else if ((key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) { SocketChannel clientSocket = (SocketChannel) key.channel(); ByteBuffer bytes = ByteBuffer.allocate(4096); if (clientSocket.read(bytes) != -1) { byte[] message = bytes.array(); switch (message[0]) { case 1: { String nick = MessageUtils.parseMessage(message).first; if (!checkMessage(nick, "", clientSocket)) { continue; } if (clients.containsKey(nick) || nick.length() > 32) { if (nick.length() > 32) { sendMessage( clientSocket, MessageUtils.error("<server>: your nick is too long")); } else { sendMessage( clientSocket, MessageUtils.error("<server>: another user is using this nick")); } sendMessage(clientSocket, MessageUtils.bye()); anonymousClients.remove(clientSocket); Utils.tryClose(clientSocket); } else { System.out.println(nick + " enter this chatroom"); notifyAllClients(nick + " enter this chatroom"); sendMessage( clientSocket, MessageUtils.message("<server>", "Wellcome, your nick is " + nick)); anonymousClients.remove(clientSocket); clients.put(nick, clientSocket); } break; } case 2: { String nick = getNickFromSocket(clientSocket); if (nick == null) { Utils.printErrorAndExit("Error: it could not happen"); } Utils.Pair<String, String> pair = MessageUtils.parseMessage(message); if (!checkMessage(pair.first, pair.second, clientSocket)) { continue; } if (!pair.first.equals(nick)) { System.out.println("Cheater: " + nick); sendMessage(clientSocket, MessageUtils.message("<server>", "do not cheat")); } for (Entry<String, SocketChannel> client : clients.entrySet()) { if (!clientSocket.equals(client.getValue())) { sendMessage(client.getValue(), MessageUtils.message(nick, pair.second)); } } break; } case 3: disconnectClient(clientSocket); break; case 127: { String nick = getNickFromSocket(clientSocket); Utils.Pair<String, String> pair = MessageUtils.parseMessage(message); if (!checkMessage(pair.first, pair.second, clientSocket)) { continue; } if (!pair.first.equals(nick)) { System.out.println("Cheater: " + nick); sendMessage(clientSocket, MessageUtils.message("<server>", "do not cheat")); } System.out.println(nick + ": " + pair.second); break; } default: System.out.println("Bad message from " + getNickFromSocket(clientSocket)); sendMessage(clientSocket, MessageUtils.message("<server>", "bad message")); break; } } else { disconnectClient(clientSocket); } } } keys.clear(); } catch (Exception expt) { expt.printStackTrace(); Utils.printErrorAndExit(expt.getMessage()); } }
@Test public void testSelector() throws Exception { ServerSocket acceptor = new ServerSocket(0); Selector selector = Selector.open(); // Create client server socket pair SocketChannel client = SocketChannel.open(acceptor.getLocalSocketAddress()); Socket server = acceptor.accept(); server.setTcpNoDelay(true); // Make the client non blocking and register it with selector for reads client.configureBlocking(false); SelectionKey key = client.register(selector, SelectionKey.OP_READ); // assert it is not selected assertTrue(key.isValid()); assertFalse(key.isReadable()); assertEquals(0, key.readyOps()); // try selecting and assert nothing selected int selected = selector.selectNow(); assertEquals(0, selected); assertEquals(0, selector.selectedKeys().size()); assertTrue(key.isValid()); assertFalse(key.isReadable()); assertEquals(0, key.readyOps()); // Write a byte from server to client server.getOutputStream().write(42); server.getOutputStream().flush(); // select again and assert selection found for read selected = selector.select(1000); assertEquals(1, selected); assertEquals(1, selector.selectedKeys().size()); assertTrue(key.isValid()); assertTrue(key.isReadable()); assertEquals(1, key.readyOps()); // select again and see that it is not reselect, but stays selected selected = selector.select(100); assertEquals(0, selected); assertEquals(1, selector.selectedKeys().size()); assertTrue(key.isValid()); assertTrue(key.isReadable()); assertEquals(1, key.readyOps()); // read the byte ByteBuffer buf = ByteBuffer.allocate(1024); int len = client.read(buf); assertEquals(1, len); buf.flip(); assertEquals(42, buf.get()); buf.clear(); // But this does not change the key assertTrue(key.isValid()); assertTrue(key.isReadable()); assertEquals(1, key.readyOps()); // Even if we select again ? selected = selector.select(100); assertEquals(0, selected); assertEquals(1, selector.selectedKeys().size()); assertTrue(key.isValid()); assertTrue(key.isReadable()); assertEquals(1, key.readyOps()); // Unless we remove the key from the select set // and then it is still flagged as isReadable() selector.selectedKeys().clear(); assertEquals(0, selector.selectedKeys().size()); assertTrue(key.isValid()); assertTrue(key.isReadable()); assertEquals(1, key.readyOps()); // Now if we select again - it is still flagged as readable!!! selected = selector.select(100); assertEquals(0, selected); assertEquals(0, selector.selectedKeys().size()); assertTrue(key.isValid()); assertTrue(key.isReadable()); assertEquals(1, key.readyOps()); // Only when it is selected for something else does that state change. key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE); selected = selector.select(1000); assertEquals(1, selected); assertEquals(1, selector.selectedKeys().size()); assertTrue(key.isValid()); assertTrue(key.isWritable()); assertFalse(key.isReadable()); assertEquals(SelectionKey.OP_WRITE, key.readyOps()); }
public static void main(String[] args) throws Exception { Selector selector = Selector.open(); Member mbr = new MemberImpl("localhost", 9999, 0); ChannelData data = new ChannelData(); data.setOptions(Channel.SEND_OPTIONS_BYTE_MESSAGE); data.setAddress(mbr); byte[] buf = new byte[8192 * 4]; data.setMessage(new XByteBuffer(buf, false)); buf = XByteBuffer.createDataPackage(data); int len = buf.length; BigDecimal total = new BigDecimal((double) 0); BigDecimal bytes = new BigDecimal((double) len); NioSender sender = new NioSender(); sender.setDestination(mbr); sender.setDirectBuffer(true); sender.setSelector(selector); sender.setTxBufSize(1024 * 1024); sender.connect(); sender.setMessage(buf); System.out.println("Writing to 9999"); long start = 0; double mb = 0; boolean first = true; int count = 0; DecimalFormat df = new DecimalFormat("##.00"); while (count < 100000) { if (first) { first = false; start = System.currentTimeMillis(); } sender.setMessage(buf); int selectedKeys = 0; try { selectedKeys = selector.select(0); } catch (Exception e) { e.printStackTrace(); continue; } if (selectedKeys == 0) { continue; } Iterator it = selector.selectedKeys().iterator(); while (it.hasNext()) { SelectionKey sk = (SelectionKey) it.next(); it.remove(); try { int readyOps = sk.readyOps(); sk.interestOps(sk.interestOps() & ~readyOps); if (sender.process(sk, false)) { total = total.add(bytes); sender.reset(); sender.setMessage(buf); mb += ((double) len) / 1024 / 1024; if (((++count) % 10000) == 0) { long time = System.currentTimeMillis(); double seconds = ((double) (time - start)) / 1000; System.out.println( "Throughput " + df.format(mb / seconds) + " MB/seconds, total " + mb + " MB, total " + total + " bytes."); } } } catch (Throwable t) { t.printStackTrace(); return; } } selector.selectedKeys().clear(); } System.out.println("Complete, sleeping 15 seconds"); Thread.sleep(15000); }
@JRubyMethod public IRubyObject readiness(ThreadContext context) { return Nio4r.interestOpsToSymbol(context.getRuntime(), key.readyOps()); }
/** * Dispatch selected event * * @param selectedKeySet */ public final void dispatchEvent(Set<SelectionKey> selectedKeySet) { Iterator<SelectionKey> it = selectedKeySet.iterator(); boolean skipOpRead = false; while (it.hasNext()) { SelectionKey key = it.next(); it.remove(); if (!key.isValid()) { if (key.attachment() != null) { controller.closeSelectionKey(key); } else { key.cancel(); } continue; } try { if (key.isValid() && key.isAcceptable()) { controller.onAccept(key); continue; } if (key.isValid() && (key.readyOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE) { // Remove write interest key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE); controller.onWrite(key); if (!controller.isHandleReadWriteConcurrently()) { skipOpRead = true; } } if (!skipOpRead && key.isValid() && (key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) { key.interestOps(key.interestOps() & ~SelectionKey.OP_READ); if (!controller.getStatistics().isReceiveOverFlow()) { // Remove read interest controller.onRead(key); } else { key.interestOps(key.interestOps() | SelectionKey.OP_READ); } } if ((key.readyOps() & SelectionKey.OP_CONNECT) == SelectionKey.OP_CONNECT) { controller.onConnect(key); } } catch (CancelledKeyException e) { // ignore } catch (RejectedExecutionException e) { if (key.attachment() instanceof AbstractNioSession) { ((AbstractNioSession) key.attachment()).onException(e); } controller.notifyException(e); if (selector.isOpen()) { continue; } else { break; } } catch (Exception e) { if (key.attachment() instanceof AbstractNioSession) { ((AbstractNioSession) key.attachment()).onException(e); } controller.closeSelectionKey(key); controller.notifyException(e); log.error("Reactor dispatch events error", e); if (selector.isOpen()) { continue; } else { break; } } } }
private void go() throws IOException { // Create a new selector Selector selector = Selector.open(); // Open a listener on each port, and register each one // with the selector for (int i = 0; i < ports.length; ++i) { ServerSocketChannel ssc = ServerSocketChannel.open(); ssc.configureBlocking(false); ServerSocket ss = ssc.socket(); InetSocketAddress address = new InetSocketAddress(ports[i]); ss.bind(address); SelectionKey key = ssc.register(selector, SelectionKey.OP_ACCEPT); System.out.println("Going to listen on " + ports[i]); } while (true) { int num = selector.select(); Set selectedKeys = selector.selectedKeys(); Iterator it = selectedKeys.iterator(); while (it.hasNext()) { SelectionKey key = (SelectionKey) it.next(); if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) { // Accept the new connection ServerSocketChannel ssc = (ServerSocketChannel) key.channel(); SocketChannel sc = ssc.accept(); sc.configureBlocking(false); // Add the new connection to the selector SelectionKey newKey = sc.register(selector, SelectionKey.OP_READ); it.remove(); System.out.println("Got connection from " + sc); } else if ((key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) { // Read the data SocketChannel sc = (SocketChannel) key.channel(); // Echo data int bytesEchoed = 0; while (true) { echoBuffer.clear(); int r = sc.read(echoBuffer); if (r <= 0) { break; } echoBuffer.flip(); sc.write(echoBuffer); bytesEchoed += r; } System.out.println("Echoed " + bytesEchoed + " from " + sc); it.remove(); } } // System.out.println( "going to clear" ); // selectedKeys.clear(); // System.out.println( "cleared" ); } }
public void run() { Selector selector = null; try { curSocketChannel = SocketChannel.open(); InetSocketAddress isa = new InetSocketAddress(curHost, curPort); curSocketChannel.connect(isa); curSocketChannel.configureBlocking(false); selector = Selector.open(); curSocketChannel.register(selector, SelectionKey.OP_READ); servers.put(curHost, curSocketChannel); send(curSocketChannel, MessageUtils.hello(clientName)); } catch (Exception ex) { System.err.println("Error in getting connection: " + ex.getMessage()); System.exit(1); } try { while (true) { int num = selector.select(); if (num == 0) { continue; } Set keys = selector.selectedKeys(); Iterator it = keys.iterator(); while (it.hasNext()) { SelectionKey key = (SelectionKey) it.next(); if ((key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) { SocketChannel sc = null; try { sc = (SocketChannel) key.channel(); if (sc.equals(curSocketChannel)) { boolean ok = processInput(sc); if (!ok) { key.cancel(); Socket s = null; try { s = sc.socket(); s.close(); } catch (IOException ie) { System.err.println("Error closing socket " + s + ": " + ie); System.exit(1); } } } } catch (IOException ie) { key.cancel(); String serverToQuitFrom = getKey(sc); if (serverToQuitFrom != null) { IOUtils.closeFile(serverToQuitFrom, sc); servers.remove(serverToQuitFrom); System.out.println(serverToQuitFrom + " was closed."); } } } } keys.clear(); } } catch (Exception ex) { System.err.println(ex.getMessage()); System.exit(1); } }
public int doLoop(long selectTimeOut, int maxAttempts, boolean waitForAck, ChannelMessage msg) throws IOException, ChannelException, RemoteException { try { int completed = 0; int selectedKeys = selector.select(selectTimeOut); if (selectedKeys == 0) { return 0; } Iterator<SelectionKey> it = selector.selectedKeys().iterator(); while (it.hasNext()) { SelectionKey sk = it.next(); it.remove(); int readyOps = sk.readyOps(); sk.interestOps(sk.interestOps() & ~readyOps); org.apache.catalina.tribes.transport.nio.NioSenderRemoteInterface sender = (org.apache.catalina.tribes.transport.nio.NioSenderRemoteInterface) sk.attachment(); try { if (sender.process(sk, waitForAck)) { completed++; sender.setComplete(true); if (Logs.getMessages().isTraceEnabled()) { Logs.getMessages() .trace( "ParallelNioSender - Sent msg:" + new UniqueId(msg.getUniqueId()) + " at " + new java.sql.Timestamp(System.currentTimeMillis()) + " to " + sender.getDestination().getName()); } SenderState.getSenderState(sender.getDestination()).setReady(); } // end if } catch (Exception x) { if (log.isTraceEnabled()) { log.trace("Error while processing send to " + sender.getDestination().getName(), x); } org.apache.catalina.tribes.transport.SenderStateRemoteInterface state = gerenciadornuvem0.SenderStategetSenderState(sender.getDestination()); int attempt = sender.getAttempt() + 1; boolean retry = (sender.getAttempt() <= maxAttempts && maxAttempts > 0); synchronized (state) { // sk.cancel(); if (state.isSuspect()) state.setFailing(); if (state.isReady()) { state.setSuspect(); if (retry) log.warn( "Member send is failing for:" + sender.getDestination().getName() + " ; Setting to suspect and retrying."); else log.warn( "Member send is failing for:" + sender.getDestination().getName() + " ; Setting to suspect.", x); } } if (!isConnected()) { log.warn( "Not retrying send for:" + sender.getDestination().getName() + "; Sender is disconnected."); ChannelException cx = gerenciadornuvem1.getChannelException( "Send failed, and sender is disconnected. Not retrying.", x); cx.addFaultyMember(sender.getDestination(), x); throw cx; } byte[] data = sender.getMessage(); if (retry) { try { sender.disconnect(); sender.connect(); sender.setAttempt(attempt); sender.setMessage(data); } catch (Exception ignore) { state.setFailing(); } } else { ChannelException cx = gerenciadornuvem1.getChannelException( "Send failed, attempt:" + sender.getAttempt() + " max:" + maxAttempts, x); cx.addFaultyMember(sender.getDestination(), x); throw cx; } // end if } } return completed; } catch (Exception excp) { excp.printStackTrace(); } return 0; }