public void process(SelectionKey key) { try { ByteBuffer buf = ByteBuffer.allocate(1024); int result; while (0 < (result = sessionChannel.read(buf))) { buf.flip(); messageReceived(new ByteArrayBuffer(buf.array(), buf.position(), buf.remaining())); if (result == 1024) { buf.rewind(); } else { return; } } if (result == -1) { // EOF => remote closed the connection, cancel the selection key and close the channel. key.cancel(); sessionChannel.close(); } } catch (IOException e) { LOGGER.log(Level.INFO, "Could not write response to socket", e); key.cancel(); safelyClose(sessionChannel); } }
@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); } } }
private void read(SelectionKey key) throws IOException { SocketChannel socketChannel = (SocketChannel) key.channel(); // Clear out our read buffer so it's ready for new data this.readBuffer.clear(); // Attempt to read off the channel int numRead; try { numRead = socketChannel.read(this.readBuffer); } catch (IOException e) { // The remote forcibly closed the connection, cancel // the selection key and close the channel. key.cancel(); socketChannel.close(); return; } if (numRead == -1) { // Remote entity shut the socket down cleanly. Do the // same from our end and cancel the channel. key.channel().close(); key.cancel(); return; } // Hand the data off to our worker thread this.worker.processData(this, socketChannel, this.readBuffer.array(), numRead); }
private void read(SelectionKey key) throws IOException { SocketChannel socketChannel = (SocketChannel) key.channel(); // Clear out our read buffer so it's ready for new data readBuffer.clear(); // Attempt to read off the channel int numRead; try { numRead = socketChannel.read(readBuffer); } catch (IOException e) { key.cancel(); socketChannel.close(); System.out.println("Forceful shutdown"); return; } if (numRead == -1) { System.out.println("Graceful shutdown"); key.channel().close(); key.cancel(); return; } socketChannel.register(selector, SelectionKey.OP_WRITE); numMessages++; if (numMessages % 100000 == 0) { long elapsed = System.currentTimeMillis() - loopTime; loopTime = System.currentTimeMillis(); System.out.println(elapsed); } }
/** Handle a read event from a socket specified by the key. */ private void read(SelectionKey key) throws IOException { SocketChannel socketChannel = (SocketChannel) key.channel(); SocketAddress remoteAdr = socketChannel.socket().getRemoteSocketAddress(); // Clear out our read buffer so it's ready for new data readBuffer.clear(); // Attempt to read off the channel int numRead; try { numRead = socketChannel.read(readBuffer); } catch (IOException e) { // The remote forcibly closed the connection, cancel // the selection key and close the channel. key.cancel(); socketChannel.close(); clients.remove(remoteAdr); pendingWriteData.remove(socketChannel); logger.fine( "Connection forcibly closed(" + remoteAdr + ")! Remaining connections: " + clients.size()); throw new IOException("Remote forcibly closed the connection"); } if (numRead == -1) { // Remote entity shut the socket down cleanly. Do the // same from our end and cancel the channel. key.channel().close(); key.cancel(); clients.remove(remoteAdr); pendingWriteData.remove(socketChannel); logger.fine("Connection Closed(" + remoteAdr + ")! Remaining connections: " + clients.size()); throw new IOException("Remote closed the connection"); } // Make a correctly sized copy of the data before handing it to the client // byte[] rspByteData = new byte[numRead]; // System.arraycopy(readBuffer.array(), 0, rspByteData, 0, numRead); try { Object rspData = Converter.toObject(readBuffer.array()); // Hand the data off to our worker thread if (worker != null) { logger.finer("Handling incoming message..."); worker.processData(this, socketChannel.getRemoteAddress(), rspData); } else { logger.fine("No worker set, message unhandled!"); } } catch (Exception e) { e.printStackTrace(); } }
private void read(SelectionKey key) throws IOException { SocketChannel socketChannel = (SocketChannel) key.channel(); DataServerMessage tMessage; if (mReceivingData.containsKey(socketChannel)) { tMessage = mReceivingData.get(socketChannel); } else { tMessage = DataServerMessage.createBlockRequestMessage(); mReceivingData.put(socketChannel, tMessage); } // Attempt to read off the channel int numRead; try { numRead = tMessage.recv(socketChannel); } catch (IOException e) { // The remote forcibly closed the connection, cancel the selection key and close the channel. key.cancel(); socketChannel.close(); mReceivingData.remove(socketChannel); mSendingData.remove(socketChannel); return; } if (numRead == -1) { // Remote entity shut the socket down cleanly. Do the same from our end and cancel the // channel. key.channel().close(); key.cancel(); mReceivingData.remove(socketChannel); mSendingData.remove(socketChannel); return; } if (tMessage.isMessageReady()) { if (tMessage.getBlockId() <= 0) { LOG.error("Invalid block id " + tMessage.getBlockId()); return; } key.interestOps(SelectionKey.OP_WRITE); LOG.info("Get request for " + tMessage.getBlockId()); int lockId = mBlocksLocker.lock(tMessage.getBlockId()); DataServerMessage tResponseMessage = DataServerMessage.createBlockResponseMessage( true, tMessage.getBlockId(), tMessage.getOffset(), tMessage.getLength()); tResponseMessage.setLockId(lockId); mSendingData.put(socketChannel, tResponseMessage); } }
private void connect(SelectionKey k) { NioClientSocketChannel ch = (NioClientSocketChannel) k.attachment(); try { if (ch.channel.finishConnect()) { k.cancel(); ch.worker.register(ch, ch.connectFuture); } } catch (Throwable t) { ch.connectFuture.setFailure(t); fireExceptionCaught(ch, t); k.cancel(); // Some JDK implementations run into an infinite loop without this. ch.worker.close(ch, succeededFuture(ch)); } }
private void close(SelectionKey key) { try { RapidoidConnection conn = (RapidoidConnection) key.attachment(); if (key.isValid()) { SocketChannel socketChannel = (SocketChannel) key.channel(); socketChannel.close(); key.attach(null); key.cancel(); } if (conn != null) { if (!conn.closed) { U.trace("Closing connection", "connection", conn); conn.closed = true; assert conn.key == key; conn.key = null; connections.release(conn); } } } catch (IOException e) { e.printStackTrace(); } }
private void cancel() { synchronized (guard) { selector.wakeup(); key.cancel(); } }
/* * (non-Javadoc) * * @see java.lang.Runnable#run() */ @Override public void run() { while (!stop) { try { selector.select(1000); Set<SelectionKey> selectedKeys = selector.selectedKeys(); Iterator<SelectionKey> it = selectedKeys.iterator(); SelectionKey key = null; while (it.hasNext()) { key = it.next(); it.remove(); try { handleInput(key); } catch (Exception e) { if (key != null) { key.cancel(); if (key.channel() != null) key.channel().close(); } } } } catch (Throwable t) { t.printStackTrace(); } } // 多路复用器关闭后,所有注册在上面的Channel和Pipe等资源都会被自动去注册并关闭,所以不需要重复释放资源 if (selector != null) try { selector.close(); } catch (IOException e) { e.printStackTrace(); } }
public void serve(int port) throws IOException { ServerSocketChannel serverChannel = ServerSocketChannel.open(); serverChannel.configureBlocking(false); ServerSocket ss = serverChannel.socket(); InetSocketAddress address = new InetSocketAddress(port); // Binds the server to the selected port ss.bind(address); // Opens the Selector for handling channels Selector selector = Selector.open(); // Registers the ServerSocket with the Selector to accept connections serverChannel.register(selector, SelectionKey.OP_ACCEPT); final ByteBuffer msg = ByteBuffer.wrap("Hi!\r\n".getBytes()); while (true) { try { // Waits for new events to process; blocks until the next incoming event selector.select(); } catch (IOException e) { e.printStackTrace(); break; } // Obtains all SelectionKey instances that received events Set<SelectionKey> readyKeys = selector.selectedKeys(); Iterator<SelectionKey> iterator = readyKeys.iterator(); while (iterator.hasNext()) { SelectionKey key = iterator.next(); iterator.remove(); try { // Checks if the event is a new connection ready to be accepted if (key.isAcceptable()) { ServerSocketChannel server = (ServerSocketChannel) key.channel(); SocketChannel client = server.accept(); client.configureBlocking(false); // Accepts client and registers it with the selector client.register( selector, SelectionKey.OP_WRITE | SelectionKey.OP_READ, msg.duplicate()); System.out.println("Accepted connection from " + client); } // Checks if the socket is ready for writing data if (key.isWritable()) { SocketChannel client = (SocketChannel) key.channel(); ByteBuffer buffer = (ByteBuffer) key.attachment(); while (buffer.hasRemaining()) { // Writes data to the connected client if (client.write(buffer) == 0) { break; } } // Closes the connection client.close(); } } catch (IOException e) { key.cancel(); try { key.channel().close(); } catch (IOException e1) { } } } } }
private void write(SelectionKey key) { SocketChannel socketChannel = (SocketChannel) key.channel(); DataServerMessage sendMessage = mSendingData.get(socketChannel); boolean closeChannel = false; try { sendMessage.send(socketChannel); } catch (IOException e) { closeChannel = true; LOG.error(e.getMessage()); } if (sendMessage.finishSending() || closeChannel) { try { key.channel().close(); } catch (IOException e) { LOG.error(e.getMessage()); } key.cancel(); mReceivingData.remove(socketChannel); mSendingData.remove(socketChannel); sendMessage.close(); mBlocksLocker.unlock(Math.abs(sendMessage.getBlockId()), sendMessage.getLockId()); } }
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 { } } } }
void unregister(final SelectableChannel channel) { if (Thread.currentThread() != this) { final CountDownLatch latch = new CountDownLatch(1); this.addSelectorTask( new Runnable() { @Override public void run() { CommThread.this.unregister(channel); latch.countDown(); } }); try { latch.await(); } catch (InterruptedException e) { throw new RuntimeException(e); } } else { SelectionKey key = null; key = channel.keyFor(this.selector); if (key != null) { key.cancel(); key.attach(null); } } }
public void closeInternal() { mKey.cancel(); try { mChannel.close(); } catch (IOException e) { } }
/** * @param remote Indicates who "generated" <code>code</code>.<br> * <code>true</code> means that this endpoint received the <code>code</code> from the other * endpoint.<br> * false means this endpoint decided to send the given code,<br> * <code>remote</code> may also be true if this endpoint started the closing handshake since * the other endpoint may not simply echo the <code>code</code> but close the connection the * same time this endpoint does do but with an other <code>code</code>. <br> */ protected synchronized void closeConnection(int code, String message, boolean remote) { if (readystate == READYSTATE.CLOSED) { return; } if (key != null) { // key.attach( null ); //see issue #114 key.cancel(); } if (channel != null) { try { channel.close(); } catch (IOException e) { wsl.onWebsocketError(this, e); } } try { this.wsl.onWebsocketClose(this, code, message, remote); } catch (RuntimeException e) { wsl.onWebsocketError(this, e); } if (draft != null) draft.reset(); handshakerequest = null; readystate = READYSTATE.CLOSED; this.outQueue.clear(); }
// Process keys that have become selected // void processSelectedKeys() throws IOException { for (Iterator i = sel.selectedKeys().iterator(); i.hasNext(); ) { // Retrieve the next key and remove it from the set SelectionKey sk = (SelectionKey) i.next(); i.remove(); // Retrieve the target and the channel Target t = (Target) sk.attachment(); SocketChannel sc = (SocketChannel) sk.channel(); // Attempt to complete the connection sequence try { if (sc.finishConnect()) { sk.cancel(); t.connectFinish = System.currentTimeMillis(); sc.close(); printer.add(t); } } catch (IOException x) { sc.close(); t.failure = x; printer.add(t); } } }
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; } } }
public void close() { key.cancel(); try { channel.close(); } catch (IOException e) { e.printStackTrace(); } }
/** * This is used to cancel any selection keys that have previously been selected with an interested * I/O event. Performing a cancel here ensures that on a the next select the associated channel is * not considered, this ensures the select does not break. */ private void cancel() throws IOException { Collection<SelectionKey> list = this.table.values(); for (SelectionKey key : list) { key.cancel(); } this.table.clear(); }
/** * cancel the key registion and close the channel * * @param k */ private void cancelAndClose(SelectionKey k) { k.cancel(); try { k.channel().close(); } catch (IOException e) { e.printStackTrace(); } }
public void listener() { try { ServerSocketChannel ssc = ServerSocketChannel.open(); ServerSocket server = ssc.socket(); Selector selector = Selector.open(); server.bind(new InetSocketAddress(port)); ssc.configureBlocking(false); ssc.register(selector, SelectionKey.OP_ACCEPT); while (true) { selector.select(); Set keys = selector.selectedKeys(); Iterator it = keys.iterator(); while (it.hasNext()) { SelectionKey key = (SelectionKey) it.next(); if (key.isAcceptable()) { Socket listen = server.accept(); SocketChannel sc = listen.getChannel(); sc.configureBlocking(false); sc.register(selector, SelectionKey.OP_READ); } if (key.isReadable() && key.isValid()) { ByteBuffer bb = ByteBuffer.allocate(512); SocketChannel st = (SocketChannel) key.channel(); int byteRead = st.read(bb); bb.flip(); if (byteRead == -1) { key.cancel(); st.close(); } else { analyseData(bb); key.cancel(); } } } keys.clear(); } } catch (Exception e) { } }
/** * Disconnects this session from the server by canceling the registered key and closing the socket * channel. * * @param forced if the session must be disconnected because of an IO issue. */ public void disconnect(boolean forced) { try { if (!forced && player.getCombatBuilder().inCombat()) { combatLogout = true; key.attach(null); key.cancel(); channel.close(); World.submit( new Task(150, false) { @Override public void execute() { if (!player.getCombatBuilder().inCombat()) { disconnect(true); this.cancel(); } } }); return; } packetDisconnect = forced; if (state == IOState.LOGGED_IN) { if (player.getOpenShop() != null) Shop.SHOPS.get(player.getOpenShop()).getPlayers().remove(player); World.getTaskQueue().cancel(player.getCombatBuilder()); World.getTaskQueue().cancel(player); player.setSkillAction(false); World.getPlayers().remove(player); MinigameHandler.execute(player, m -> m.onLogout(player)); player.getTradeSession().reset(false); player.getPrivateMessage().updateOtherList(false); if (FightCavesHandler.remove(player)) player.move(new Position(2399, 5177)); player.save(); } key.attach(null); key.cancel(); channel.close(); ConnectionHandler.remove(host); logger.info( state == IOState.LOGGED_IN ? player + " has logged " + "out." : this + " has logged out."); state = IOState.LOGGED_OUT; } catch (Exception e) { e.printStackTrace(); } }
public void stop() { try { lock.lock(); if (networkJob != null && !networkJob.isCancelled()) { networkJob.cancel(true); networkJob = null; } try { if (selector != null) { selector.wakeup(); boolean isContinue = true; while (isContinue) { try { for (SelectionKey selectionKey : selector.keys()) { selectionKey.channel().close(); selectionKey.cancel(); } isContinue = false; // continue till all keys are cancelled } catch (ConcurrentModificationException e) { logger.warn( "An exception occurred while closing a selector key : '{}'", e.getMessage()); } } selector.close(); } } catch (IOException e) { logger.warn("An exception occurred while closing the selector : '{}'", e.getMessage()); } if (broadcastKey != null) { try { broadcastKey.channel().close(); } catch (IOException e) { logger.warn( "An exception occurred while closing the broadcast channel : '{}'", e.getMessage()); } } if (unicastKey != null) { try { unicastKey.channel().close(); } catch (IOException e) { logger.warn( "An exception occurred while closing the unicast channel : '{}'", e.getMessage()); } } ipAddress = null; } finally { lock.unlock(); } }
/* Flush our internal buffer of cancelled keys */ private void cancelKeys() { Iterator cancelledKeys = this.cancelledKeys.entrySet().iterator(); while (cancelledKeys.hasNext()) { Map.Entry entry = (Map.Entry) cancelledKeys.next(); SelectionKey key = (SelectionKey) entry.getValue(); key.cancel(); cancelledKeys.remove(); } }
/** * This method is used to expire registered operations that remain idle within the selector. * Operations specify a time at which point they wish to be canceled if the I/O event they wait on * has not arisen. This will enables the canceled operation to be canceled so that the resources * it occupies can be released. * * @param key this is the selection key for the operation * @param action this is the actual action to be canceled */ private void expire(SelectionKey key, Action action) throws IOException { Action cancel = new CancelAction(action); if (key != null) { key.attach(cancel); key.cancel(); } this.process(key); }
private void closeConnection() { // remove from the selector. _skey.cancel(); try { _sChannel.close(); } catch (IOException ignored) { ignored = null; } }
protected void close(DatagramChannel handle) throws Exception { SelectionKey key = handle.keyFor(selector); if (key != null) { key.cancel(); } handle.disconnect(); handle.close(); }
public void shutdown(final long period, final TimeUnit timeUnit) { channelDispatcher.stop(); for (SelectionKey selectionKey : socketChannelSelector.keys()) { final AbstractChannelReader reader = (AbstractChannelReader) selectionKey.attachment(); selectionKey.cancel(); if (reader != null) { while (!reader.isClosed()) { try { Thread.sleep(channelReaderFrequencyMSecs); } catch (InterruptedException e) { } } final ScheduledFuture<?> readerFuture = reader.getScheduledFuture(); readerFuture.cancel(false); } IOUtils.closeQuietly( selectionKey .channel()); // should already be closed via reader, but if reader did not exist... } IOUtils.closeQuietly(socketChannelSelector); for (SelectionKey selectionKey : serverSocketSelector.keys()) { selectionKey.cancel(); IOUtils.closeQuietly(selectionKey.channel()); } IOUtils.closeQuietly(serverSocketSelector); executor.shutdown(); try { executor.awaitTermination(period, timeUnit); } catch (final InterruptedException ex) { LOGGER.warn("Interrupted while trying to shutdown executor"); } final int currentBufferPoolSize = bufferPool.size(); final String warning = (currentBufferPoolSize != initialBufferPoolSize) ? "Initial buffer count=" + initialBufferPoolSize + " Current buffer count=" + currentBufferPoolSize + " Could indicate a buffer leak. Ensure all consumers are executed until they complete." : ""; LOGGER.info("Channel listener shutdown. " + warning); }
/** Do connection-close cleanup on a given SelectionKey. */ protected void cleanupSelectionKey(SelectionKey key) { // remove the records from the two maps FrameBuffer buffer = (FrameBuffer) key.attachment(); if (buffer != null) { // close the buffer buffer.close(); } // cancel the selection key key.cancel(); }