/** * Start the server running - accepting connections, receiving messages. If the server is already * running, it will not be started again. This method is designed to be called in its own thread * and will not return until the server is stopped. * * @throws RuntimeException if the server fails */ public void run() { // ensure that the server is not started twice if (!state.compareAndSet(State.STOPPED, State.RUNNING)) { started(true); return; } Selector selector = null; ServerSocketChannel server = null; try { selector = Selector.open(); server = ServerSocketChannel.open(); server.socket().bind(new InetSocketAddress(port)); server.configureBlocking(false); server.register(selector, SelectionKey.OP_ACCEPT); started(false); while (state.get() == State.RUNNING) { selector.select(100); // check every 100ms whether the server has been requested to stop for (Iterator<SelectionKey> it = selector.selectedKeys().iterator(); it.hasNext(); ) { SelectionKey key = it.next(); try { // remove key from the ready list it.remove(); if (key.isConnectable()) { ((SocketChannel) key.channel()).finishConnect(); } if (key.isAcceptable()) { // accept connection SocketChannel client = server.accept(); client.configureBlocking(false); client.socket().setTcpNoDelay(true); // channel is registered for further events such as read or write SelectionKey acceptKey = client.register(selector, SelectionKey.OP_READ); connection(acceptKey); } if (key.isReadable()) { for (ByteBuffer message : readIncomingMessage(key)) { messageReceived(message, key); } } } catch (IOException ioe) { resetKey(key); disconnected(key); } } } } catch (Throwable e) { throw new RuntimeException("Server failure: " + e.getMessage()); } finally { try { selector.close(); server.socket().close(); server.close(); state.set(State.STOPPED); stopped(); } catch (Exception e) { // do nothing - server failed } } }
/** Selects on sockets and informs their Communicator when there is something to do. */ public void communicate(int timeout) { try { selector.select(timeout); } catch (IOException e) { // Not really sure why/when this happens yet return; } Iterator<SelectionKey> keys = selector.selectedKeys().iterator(); while (keys.hasNext()) { SelectionKey key = keys.next(); keys.remove(); if (!key.isValid()) continue; // WHY Communicator communicator = (Communicator) key.attachment(); if (key.isReadable()) communicator.onReadable(); if (key.isWritable()) communicator.onWritable(); if (key.isAcceptable()) communicator.onAcceptable(); } // Go through the queue and handle each communicator while (!queue.isEmpty()) { Communicator c = queue.poll(); c.onMemo(); } }
public static void main(String[] args) throws IOException { ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.socket().bind(new InetSocketAddress(PORT)); System.out.println("Server listening at port : " + PORT); serverSocketChannel.configureBlocking(false); Selector selector = Selector.open(); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); while (true) { int n = selector.select(); if (n == 0) { continue; } Iterator<SelectionKey> it = selector.selectedKeys().iterator(); while (it.hasNext()) { SelectionKey key = it.next(); if (key.isAcceptable()) { ServerSocketChannel ssc = (ServerSocketChannel) key.channel(); SocketChannel sc = ssc.accept(); sc.configureBlocking(false); sc.register(selector, SelectionKey.OP_READ); System.out.println("accept client : " + sc); acceptClient(sc); } if (key.isReadable()) { readData(key); } it.remove(); } } }
private void dispatchMessages() throws IOException { Iterator<SelectionKey> it = selector.selectedKeys().iterator(); while (it.hasNext()) { SelectionKey key = it.next(); EventSource source = (EventSource) key.attachment(); if (key.isValid()) { try { if (key.isAcceptable()) { EventSource newSource = source.accept(); if (newSource != null) newSources.add(newSource); } if (key.isReadable()) { source.read(); } if (key.isWritable()) { source.write(); } } catch (CancelledKeyException e) { } } it.remove(); } for (int i = 0; i < newSources.size(); i++) register(newSources.get(i)); if (!newSources.isEmpty()) newSources.clear(); }
public void run() { try { while (!flag) { System.out.println("waiting connected......."); selector.select(); Iterator<SelectionKey> keys = selector.selectedKeys().iterator(); while (keys.hasNext()) { SelectionKey key = keys.next(); keys.remove(); if (key.isAcceptable()) { ServerSocketChannel ssc = (ServerSocketChannel) key.channel(); SocketChannel sc = ssc.accept(); sc.configureBlocking(false); SelectionKey clientKey = sc.register(selector, SelectionKey.OP_READ); System.out.println(sc.socket().getInetAddress().getHostAddress() + " 已连接"); } if (key.isReadable()) { read(key); } } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
// actual connection logic private void _connect() throws IOException { // Continuous loop that is only supposed to end when "close" is called. selector.select(); Set<SelectionKey> keys = selector.selectedKeys(); Iterator<SelectionKey> i = keys.iterator(); while (i.hasNext()) { SelectionKey key = i.next(); i.remove(); if (key.isConnectable()) { if (socketChannel.isConnectionPending()) { socketChannel.finishConnect(); } socketChannel.register(selector, SelectionKey.OP_READ); _writeHandshake(); } if (key.isReadable()) { try { _read(); } catch (NoSuchAlgorithmException nsa) { this.onError(nsa); } } } }
private void loop() { while (true) { try { selector.select(); Iterator<SelectionKey> selectedKeys = selector.selectedKeys().iterator(); while (selectedKeys.hasNext()) { SelectionKey key = selectedKeys.next(); selectedKeys.remove(); if (!key.isValid()) { continue; } // Check what event is available and deal with it if (key.isAcceptable()) { accept(key); } else if (key.isReadable()) { read(key); } else if (key.isWritable()) { write(key); } } } catch (Exception e) { e.printStackTrace(); System.exit(1); } } }
public void actionHandler(SelectionKey key) throws IOException { if (key.isAcceptable()) { ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel(); SocketChannel socketChannel = serverChannel.accept(); socketChannel.configureBlocking(false); socketChannel.register(roller, SelectionKey.OP_READ); } else if (key.isReadable()) { ByteBuffer buffer = ByteBuffer.allocate(16); SocketChannel socketChannel = (SocketChannel) key.channel(); socketChannel.read(buffer); buffer.flip(); String temp = decode(buffer); StringBuffer strBuffer = stringLocal.get(); if (strBuffer == null) { strBuffer = new StringBuffer(); } strBuffer.append(temp); if (temp.equals("\r\n")) { System.out.println(strBuffer.toString()); strBuffer = null; } stringLocal.set(strBuffer); } }
private void handleInput(SelectionKey key) throws IOException { if (key != null && key.isValid()) { SocketChannel sc = (SocketChannel) key.channel(); if (key.isConnectable()) { if (sc.finishConnect()) { sc.register(selector, SelectionKey.OP_READ); doWrite(sc); } else System.exit(1); } if (key.isReadable()) { ByteBuffer readBuffer = ByteBuffer.allocate(1024); int readBytes = sc.read(readBuffer); if (readBytes > 0) { readBuffer.flip(); byte[] bytes = new byte[readBuffer.remaining()]; readBuffer.get(bytes); String body = new String(bytes, "UTF-8"); System.out.println("Now is : " + body); this.stop = true; } else if (readBytes < 0) { key.cancel(); sc.close(); } else { } } } }
private void processKey(SelectionKey key) { try { if (key.isReadable()) { final DatagramChannel socketChannel = (DatagramChannel) key.channel(); reader.readAll(socketChannel); } if (key.isWritable()) { final DatagramChannel socketChannel = (DatagramChannel) key.channel(); try { int bytesJustWritten = writer.writeAll(socketChannel); contemplateThrottleWrites(bytesJustWritten); } catch (NotYetConnectedException e) { if (LOG.isDebugEnabled()) LOG.debug("", e); serverConnector.connectLater(); } catch (IOException e) { if (LOG.isDebugEnabled()) LOG.debug("", e); serverConnector.connectLater(); } } } catch (Exception e) { LOG.error("", e); if (!isClosed) closeEarlyAndQuietly(key.channel()); } }
public void run() { while (true) { try { synchronized (changeRequests) { Iterator changes = changeRequests.iterator(); while (changes.hasNext()) { ChangeRequest change = (ChangeRequest) changes.next(); switch (change.type) { case ChangeRequest.CHANGEOPS: SelectionKey key = change.socket.keyFor(selector); key.interestOps(change.ops); } } changeRequests.clear(); } selector.select(); Iterator selectedKeys = selector.selectedKeys().iterator(); while (selectedKeys.hasNext()) { SelectionKey key = (SelectionKey) selectedKeys.next(); selectedKeys.remove(); if (!key.isValid()) continue; if (key.isAcceptable()) accept(key); else if (key.isReadable()) read(key); else if (key.isWritable()) write(key); } } catch (IOException e) { e.printStackTrace(); } } }
private void listen() throws IOException { while (true) { int selec = selector.select(500); if (selec == 0) { continue; } Iterator<SelectionKey> iterator = this.selector.selectedKeys().iterator(); while (iterator.hasNext()) { SelectionKey selectionKey = iterator.next(); try { iterator.remove(); if (selectionKey.isAcceptable()) { ServerSocketChannel ssc = (ServerSocketChannel) selectionKey.channel(); SocketChannel sc = ssc.accept(); sc.configureBlocking(false); sc.register(selector, SelectionKey.OP_READ); } else if (selectionKey.isReadable()) { read(selectionKey); } else if (selectionKey.isWritable()) { write(selectionKey); } } catch (Exception e) { // iterator.remove(); Don't use it! It can throw a exception! SocketChannel sc = (SocketChannel) selectionKey.channel(); sc.close(); } } } }
@Override public void run() { try { System.out.println("[Server Opened]"); selector = Selector.open(); ssc.register(selector, SelectionKey.OP_ACCEPT); while (true) { int canalsPreparats = selector.select(); if (canalsPreparats == 0) { continue; } Set<SelectionKey> clausSeleccionades = selector.selectedKeys(); Iterator<SelectionKey> iterador = clausSeleccionades.iterator(); while (iterador.hasNext()) { SelectionKey clau = iterador.next(); // CONCURRENCIA claus // Les claus son un recurs compartit, ja que quan finalitza // el joc, el métode update() les cancela. Per aquest motiu // quan en fem us, synchronitzem el objecte, i comprovem // que siguin vàlides synchronized (this) { if (clau.isValid() && clau.isAcceptable()) { ferAccept(clau); } else if (clau.isValid() && clau.isReadable()) { rebre(clau); } } iterador.remove(); } } } catch (IOException ex) { } }
private void handle(SelectionKey key) throws IOException { // TODO Auto-generated method stub ServerSocketChannel server = null; SocketChannel client = null; String receiveText = null; int count = 0; if (key.isAcceptable()) { // client require accept events server = (ServerSocketChannel) key.channel(); client = server.accept(); client.configureBlocking(false); client.register(selector, SelectionKey.OP_READ); } else if (key.isReadable()) { // 如果是read事件,则直接读取 client = (SocketChannel) key.channel(); recBuffer.clear(); count = client.read(recBuffer); if (count > 0) { recBuffer.flip(); receiveText = decode.decode(recBuffer.asReadOnlyBuffer()).toString(); System.out.println(client.toString() + ":" + receiveText); sendBuffer.clear(); sendBuffer.put((sdf.format(new Date()) + "服务器收到你的消息").getBytes()); sendBuffer.flip(); client.write(sendBuffer); dispatch(client, receiveText); client = (SocketChannel) key.channel(); client.register(selector, SelectionKey.OP_READ); } } }
@Override public void run() { Thread.currentThread().setName(threadName); while (started) { processRegisterTaskQueue(); try { if (selector.select(1000) > 0) { Iterator<SelectionKey> iter = selector.selectedKeys().iterator(); while (iter.hasNext()) { SelectionKey key = iter.next(); iter.remove(); // 处理Key if (key.isReadable()) { processReadableKey(key); } else if (key.isWritable()) { processWritableKey(key); } } // TODO shutdown } } catch (IOException e) { logger.warn("Unexpected exception in the selector loop.", e); // Prevent possible consecutive immediate failures that lead to // excessive CPU consumption. try { Thread.sleep(1000); } catch (InterruptedException t) { // Ignore. } } } }
private void do_selection() throws IOException { // wait for events // timeout 1000ms -> check for pendingChanges at least every second if (selector.select(1000) == 0) return; // wakeup to work on selected keys Iterator keys = selector.selectedKeys().iterator(); while (keys.hasNext()) { SelectionKey key = (SelectionKey) keys.next(); keys.remove(); if (!key.isValid()) { continue; } if (key.isAcceptable()) { accept(key); } else if (key.isReadable()) { read(key); } else if (key.isWritable()) { write(key); } else if (key.isConnectable()) { connect(key); } } }
/** * ������ѯ�ķ�ʽ����selector���Ƿ�����Ҫ������¼�������У�����д��� * * @throws IOException */ public void listen() { // ��ѯ����selector while (true) { int readyChannels = 0; try { readyChannels = selector.select(); if (readyChannels == 0) { continue; } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); if (selector != null) { try { selector.close(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } } // ���selector��ѡ�е���ĵ���� Iterator ite = this.selector.selectedKeys().iterator(); while (ite.hasNext()) { SelectionKey key = (SelectionKey) ite.next(); // ɾ����ѡ��key,�Է��ظ����� ite.remove(); // �����¼����� if (key.isValid() && key.isConnectable()) { SocketChannel channel = (SocketChannel) key.channel(); // ����������ӣ���������� if (channel.isConnectionPending()) { try { channel.finishConnect(); // ���óɷ����� channel.configureBlocking(false); // ��������Ը����˷�����ϢŶ channel.write(ByteBuffer.wrap(new String("�����˷�����һ����Ϣ").getBytes())); // �ںͷ�������ӳɹ�֮��Ϊ�˿��Խ��յ�����˵���Ϣ����Ҫ��ͨ�����ö���Ȩ�ޡ� channel.register(this.selector, SelectionKey.OP_READ); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); if (channel != null) { try { channel.close(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } } } } else if (key.isReadable()) { // ����˿ɶ����¼� read(key); } } } }
void handleKey(SelectionKey key, AbstractBsNet ch) { if (key.isReadable()) { // 读信息 onReadyToRead(key); } if (key.isWritable()) { // 写事件 writeInReactor((BsNetClient) ch); } }
@Override protected void processKey(SelectionKey key) throws IOException { if (key.isAcceptable()) { if (key.channel() == commandServerChannel) { acceptCommand(key); } else { if (commandChannel == null) { throw new IOException("Unexpected"); } accept(key); } } else { if (commandChannel == null) { throw new IOException("Unexpected"); } if (key.isReadable() && pendingChannels.containsKey(key.channel())) { ByteChannel channel = (ByteChannel) key.channel(); try { ByteBuffer readBuffer = pendingChannels.get(channel); int read = channel.read(readBuffer); if (read == -1) { throw new IOException("Pending channel closed"); } if (readBuffer.position() >= 5) { readBuffer.flip(); try { byte cmd = readBuffer.get(); if (cmd == CMD_OPEN_CHANNEL_ACK) { int tunnelId = readBuffer.getInt(); try { registerLeftChannel(tunnelId, channel); pendingChannels.remove(channel); } catch (IOException e) { logger.log(Level.INFO, "Spooling error: " + e.getMessage(), e); closeTunnel(tunnelId); } } else { throw new IOException("Unknown command"); } } finally { readBuffer.compact(); } } } catch (IOException e) { logger.log(Level.SEVERE, "PROTOCOL ERROR: " + e.getMessage(), e); close(channel); } } else { super.processKey(key); } } }
protected boolean isReadable(DatagramChannel handle) { SelectionKey key = handle.keyFor(selector); if ((key == null) || (!key.isValid())) { return false; } return key.isReadable(); }
private void handle(SelectionKey key) throws Exception { if (key.isValid() && key.isAcceptable()) { ChannelHandler.handlerAccpet(server, key); } else if (key.isReadable()) { ChannelHandler.handlerRead(server, key); } else if (key.isWritable()) { ChannelHandler.handlerWrite(server, key); } }
protected void handleClient(SelectionKey key) throws IOException { SocketChannel sc = (SocketChannel) key.channel(); ClientInfo ci = (ClientInfo) allClients.get(sc); if (ci == null) throw new IllegalStateException("Unknown client"); if (key.isWritable()) send(sc, ci); if (key.isReadable()) // 从一个客户端读进所有的可用数据 recv(sc, ci); }
protected String sendAndReceive(byte[] payload) throws IOException { ByteBuffer sbuf = ByteBuffer.wrap(payload); ByteBuffer rbuf = ByteBuffer.allocateDirect(256); CharsetDecoder rbufDecoder = Charset.forName("UTF-8").newDecoder(); StringBuilder response = new StringBuilder(); int ops = SelectionKey.OP_WRITE | SelectionKey.OP_READ; if (this.channel.isConnectionPending()) { ops = ops | SelectionKey.OP_CONNECT; } Selector selector = Selector.open(); try { this.channel.register(selector, ops); while (true) { if (0 < selector.select(Client.POLLS_INTERVAL * 1000)) { Iterator keys = selector.selectedKeys().iterator(); while (keys.hasNext()) { SelectionKey key = (SelectionKey) keys.next(); SocketChannel ch = (SocketChannel) key.channel(); if (key.isConnectable()) { // Just connected ch.finishConnect(); } if (key.isReadable() && !sbuf.hasRemaining()) { // Receiving the response while (0 < ch.read(rbuf)) { rbuf.flip(); response.append(rbufDecoder.decode(rbuf).toString()); } if (2 <= response.length() && response .substring(response.length() - 2, response.length()) .equals(SocketClient.TERMINATOR)) { response.setLength(response.length() - 2); return response.toString(); } else if (0 == response.length()) { throw new IOException("Connection lost"); } } if (key.isWritable() && sbuf.hasRemaining()) { // Sending the request while (0 < ch.write(sbuf) && sbuf.hasRemaining()) { // } } keys.remove(); } } } } catch (java.lang.Exception e) { throw new IOException("API communication failed: " + e.toString()); } finally { selector.close(); } }
private void clientSelected(SelectionKey key) { if (log.isDebugEnabled()) { log.debug( "Client {} selected: interest = {} r = {} w = {} c = {}", clientChannel, selKey.interestOps(), key.isReadable(), key.isWritable(), key.isConnectable()); } Context cx = Context.getCurrentContext(); if (key.isValid() && key.isConnectable()) { processConnect(cx); } if (key.isValid() && (key.isWritable() || writeReady)) { processWrites(cx); } if (key.isValid() && key.isReadable()) { processReads(cx); } }
private void dispatch() throws IOException { SelectionKey key = null; for (SocketChannelOPSChangeRequest request : opsChangeRequstMap.values()) { key = request.getChannel().keyFor(selector); if (key != null) { // 写优先 if ((request.getOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE) { key.interestOps(SelectionKey.OP_WRITE); request.clearOps(SelectionKey.OP_WRITE); } else if ((request.getOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) { key.interestOps(SelectionKey.OP_READ); request.clearOps(SelectionKey.OP_READ); } } } isWeakuped.set(false); if (selector.select(WaveriderConfig.WAVERIDER_DEFAULT_NETWORK_TIME_OUT) <= 0) { return; } Iterator<SelectionKey> iterator = selector.selectedKeys().iterator(); while (iterator.hasNext()) { key = (SelectionKey) iterator.next(); iterator.remove(); try { if (!key.isValid()) { continue; } else if (key.isAcceptable()) { onAccept(key); } else if (key.isReadable()) { // readerExecutor.execute(new NetworkTask(key, NETWORK_OPERATION_READ)); onRead(key); } else if (key.isWritable()) { // writerExecutor.execute(new NetworkTask(key, NETWORK_OPERATION_WRITE)); onWrite(key); } } catch (IOException e) { // 客户端连接出问题 Session session = (Session) key.attachment(); if (session != null) { session.onException(); // 释放Session sessionManager.freeSession(session); } opsChangeRequstMap.remove((SocketChannel) key.channel()); key.cancel(); key.channel().close(); e.printStackTrace(); logger.error("OOPS:Exception:", e); } } }
/* 350 */ while (((Iterator)localObject3).hasNext()) { /* 351 */ SelectionKey localSelectionKey = (SelectionKey)((Iterator)localObject3).next(); /* 352 */ ((Iterator)localObject3).remove(); /* 353 */ if (localSelectionKey.equals(ServerImpl.this.listenerKey)) { /* 354 */ if (!ServerImpl.this.terminating) /* */ { /* 357 */ SocketChannel localSocketChannel = ServerImpl.this.schan.accept(); /* */ /* 360 */ if (ServerConfig.noDelay()) { /* 361 */ localSocketChannel.socket().setTcpNoDelay(true); /* */ } /* */ /* 364 */ if (localSocketChannel != null) /* */ { /* 367 */ localSocketChannel.configureBlocking(false); /* 368 */ localObject4 = localSocketChannel.register(ServerImpl.this.selector, 1); /* 369 */ localHttpConnection2 = new HttpConnection(); /* 370 */ localHttpConnection2.selectionKey = ((SelectionKey)localObject4); /* 371 */ localHttpConnection2.setChannel(localSocketChannel); /* 372 */ ((SelectionKey)localObject4).attach(localHttpConnection2); /* 373 */ ServerImpl.this.requestStarted(localHttpConnection2); /* 374 */ ServerImpl.this.allConnections.add(localHttpConnection2); /* */ } /* */ } /* */ } /* */ else { /* */ try /* */ { /* */ Object localObject4; /* */ HttpConnection localHttpConnection2; /* 377 */ if (localSelectionKey.isReadable()) /* */ { /* 379 */ localObject4 = (SocketChannel)localSelectionKey.channel(); /* 380 */ localHttpConnection2 = (HttpConnection)localSelectionKey.attachment(); /* */ /* 382 */ localSelectionKey.cancel(); /* 383 */ ((SocketChannel)localObject4).configureBlocking(true); /* 384 */ if (ServerImpl.this.idleConnections.remove(localHttpConnection2)) /* */ { /* 387 */ ServerImpl.this.requestStarted(localHttpConnection2); /* */ } /* 389 */ handle((SocketChannel)localObject4, localHttpConnection2); /* */ } /* 391 */ else if (!$assertionsDisabled) { throw new AssertionError(); } /* */ } /* */ catch (CancelledKeyException localCancelledKeyException) { /* 394 */ handleException(localSelectionKey, null); /* */ } catch (IOException localIOException2) { /* 396 */ handleException(localSelectionKey, localIOException2); /* */ } /* */ } /* */ }
private void handleSelecedKeys() throws IOException { SocketChannel socketChannelForClient; Iterator<SelectionKey> iter = selector.selectedKeys().iterator(); while (iter.hasNext()) { SelectionKey selectionKey = iter.next(); // 判断事件类型 if (selectionKey.isAcceptable()) { // 请求连接事件 System.out.println("[** NIOServer **]: Handle a acceptable event!"); socketChannelForClient = serverSocketChannel.accept(); socketChannelForClient.configureBlocking(false); String responseMsg = "[$#$ From NIOServer $#$]: You has connected to server on " + bindLocalPort; byteBuffer.put(responseMsg.getBytes()); byteBuffer.flip(); while (byteBuffer.hasRemaining()) { socketChannelForClient.write(byteBuffer); } byteBuffer.clear(); socketChannelForClient.register(selector, SelectionKey.OP_READ); } else if (selectionKey.isConnectable()) { // 连接事件 System.out.println("[** NIOServer **]: Handle a connectable event!"); } else if (selectionKey.isReadable()) { // 读事件 System.out.println("[** NIOServer **]: Handle a readable event!"); byte[] msg = readMessage(selectionKey); int size = 0; for (int i = 0; i < msg.length; i++) { if (msg[i] == 0) { size = i; break; } else if (i == msg.length - 1) { size = msg.length; } } System.out.println("[** NIOServer **]: Got a message: \"" + new String(msg) + "\" \n"); sendMessage(selectionKey, "[$$ From NIOServer $$]: Got data size:" + size + "b !"); } else if (selectionKey.isWritable()) { // 写事件 System.out.println("[** NIOServer **]: Handle a writable event!"); } // 移除已经处理过的事件, 避免重复处理 iter.remove(); } }
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); } }
// Handle IO for a specific selector. Any IOException will cause a // reconnect private void handleIO(SelectionKey sk) { MemcachedNode qa = (MemcachedNode) sk.attachment(); try { getLogger() .debug( "Handling IO for: %s (r=%s, w=%s, c=%s, op=%s)", sk, sk.isReadable(), sk.isWritable(), sk.isConnectable(), sk.attachment()); if (sk.isConnectable()) { getLogger().info("Connection state changed for %s", sk); final SocketChannel channel = qa.getChannel(); if (channel.finishConnect()) { assert channel.isConnected() : "Not connected."; qa.connected(); addedQueue.offer(qa); if (qa.getWbuf().hasRemaining()) { handleWrites(sk, qa); } } else { assert !channel.isConnected() : "connected"; } } else { if (sk.isReadable()) { handleReads(sk, qa); } if (sk.isWritable()) { handleWrites(sk, qa); } } } catch (Exception e) { // Various errors occur on Linux that wind up here. However, any // particular error processing an item should simply cause us to // reconnect to the server. getLogger().info("Reconnecting due to exception on %s", qa, e); queueReconnect(qa); } qa.fixupOps(); }
static void test() throws Exception { ServerSocketChannel ssc = null; SocketChannel sc = null; SocketChannel peer = null; try { ssc = ServerSocketChannel.open().bind(new InetSocketAddress(0)); // loopback connection InetAddress lh = InetAddress.getLocalHost(); sc = SocketChannel.open(new InetSocketAddress(lh, ssc.socket().getLocalPort())); peer = ssc.accept(); // peer sends message so that "sc" will be readable int n = peer.write(ByteBuffer.wrap("Hello".getBytes())); assert n > 0; sc.configureBlocking(false); Selector selector = Selector.open(); SelectionKey key = sc.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE); boolean done = false; int failCount = 0; while (!done) { int nSelected = selector.select(); if (nSelected > 0) { if (nSelected > 1) throw new RuntimeException("More than one channel selected"); Set<SelectionKey> keys = selector.selectedKeys(); Iterator<SelectionKey> iterator = keys.iterator(); while (iterator.hasNext()) { key = iterator.next(); iterator.remove(); if (key.isWritable()) { failCount++; if (failCount > 10) throw new RuntimeException("Test failed"); Thread.sleep(250); } if (key.isReadable()) { done = true; } } } } } finally { if (peer != null) peer.close(); if (sc != null) sc.close(); if (ssc != null) ssc.close(); } }