@Override protected void writeOP(SelectionKey key) throws IOException { RapidoidConnection conn = (RapidoidConnection) key.attachment(); SocketChannel socketChannel = (SocketChannel) key.channel(); checkOnSameThread(); try { int wrote = conn.output.writeTo(socketChannel); conn.output.deleteBefore(wrote); boolean complete = conn.output.size() == 0; if (conn.closeAfterWrite() && complete) { close(conn); } else { if (complete) { key.interestOps(SelectionKey.OP_READ); } else { key.interestOps(SelectionKey.OP_READ + SelectionKey.OP_WRITE); } conn.wrote(complete); } } catch (IOException e) { close(conn); } }
/** Handle new OP_CONNECT ops. */ protected void onConnectOp(Context ctx, ConnectChannelOperation selectionKeyOp) throws IOException { SocketChannel socketChannel = (SocketChannel) selectionKeyOp.getChannel(); SocketAddress remoteAddress = selectionKeyOp.getRemoteAddress(); CallbackHandler callbackHandler = selectionKeyOp.getCallbackHandler(); CallbackHandlerSelectionKeyAttachment attachment = new CallbackHandlerSelectionKeyAttachment(callbackHandler); SelectionKey key = socketChannel.register(selector, 0, attachment); attachment.associateKey(key); boolean isConnected; try { isConnected = socketChannel.connect(remoteAddress); } catch (Exception e) { if (logger.isLoggable(Level.FINE)) { logger.log(Level.FINE, "Exception occured when tried to connect socket", e); } // set isConnected to true to let callback handler to know about the problem happened isConnected = true; } // if channel was connected immediately or exception occured if (isConnected) { onConnectInterest(key, ctx); } else { key.interestOps(SelectionKey.OP_CONNECT); } }
/** * 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 } } }
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); } }
/** * This implementation defers to the {@link #accept(SelectionKey)} method if a connection is * pending. In all other cases it defers to it's parent. * * @param key The {@link SelectionKey} for the socket on which an I/O operation is pending. * @throws IOException if an error occurs while processing the pending event. */ protected void handleSelectionKeyOperation(SelectionKey key) throws IOException { if (key.isValid() && key.isAcceptable()) { this.accept(key); } else { super.handleSelectionKeyOperation(key); } }
@GuardedBy("lock") private void setWriteOps() { // Make sure we are registered to get updated when writing is available again key.interestOps(key.interestOps() | SelectionKey.OP_WRITE); // Refresh the selector to make sure it gets the new interestOps key.selector().wakeup(); }
@Override public void run() { try { while (true) { this.selector.select(SELECT_MILLISECONDS); if (Thread.interrupted()) break; Iterator<SelectionKey> i = this.selector.selectedKeys().iterator(); while (i.hasNext()) { SelectionKey key = i.next(); SelectableChannel channel = key.channel(); handleReadableChannel(key, channel); handleWritableChannel(key, channel); i.remove(); } } } catch (ClosedByInterruptException e) { // User-requested interrupt, so clean up } catch (IOException e) { reportIOException(e); } for (Map.Entry<SelectableChannel, SelectableChannel> e : this.outputs.entrySet()) { closeChannelAndReportException(e.getKey()); closeChannelAndReportException(e.getValue()); } for (SelectableChannel c : this.outputBuffers.keySet()) closeChannelAndReportException(c); }
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(); } }
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); } } }
void unregisterChannels(SelectionKeyRegistrationReference registrationReference) throws Exception { registrationReference.cancelRegistration(); SelectorIntraband defaultIntraband = (SelectorIntraband) registrationReference.getIntraband(); Selector selector = defaultIntraband.selector; Set<SelectionKey> keys = selector.keys(); while (!keys.isEmpty()) { selector.wakeup(); } SelectionKey readSelectionKey = registrationReference.readSelectionKey; SelectionKey writeSelectionKey = registrationReference.writeSelectionKey; SelectableChannel readSelectableChannel = readSelectionKey.channel(); SelectableChannel writeSelectableChannel = writeSelectionKey.channel(); while (readSelectableChannel.keyFor(selector) != null) ; while (writeSelectableChannel.keyFor(selector) != null) ; writeSelectableChannel.close(); readSelectableChannel.close(); }
// 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); } } }
private void write(SelectionKey key) throws IOException { SocketChannel ch = (SocketChannel) key.channel(); int count = 0; synchronized (pendingData) { List queue = (List) pendingData.get(ch); /** * Null exception alert: This can happen once a connection was established. Check send() for * more information. */ if (queue == null) return; while (!queue.isEmpty()) { ByteBuffer buf = (ByteBuffer) queue.get(0); ch.write(buf); count += buf.capacity() - buf.remaining(); if (buf.remaining() > 0) break; queue.remove(0); } if (queue.isEmpty()) key.interestOps(SelectionKey.OP_READ); } if (!listener.handleWrite(ch, count)) close(ch); }
@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) { } }
@Override protected void doProcessing() { SocketChannel socketChannel; while ((socketChannel = accepted.poll()) != null) { U.debug("incoming connection", "address", socketChannel.socket().getRemoteSocketAddress()); try { SelectionKey newKey = socketChannel.register(selector, SelectionKey.OP_READ); RapidoidConnection conn = connections.get(); conn.key = newKey; if (isProtocolListener) { conn.setListener((ConnectionListener) protocol); } newKey.attach(conn); } catch (ClosedChannelException e) { U.warn("Closed channel", e); } } synchronized (done) { for (int i = 0; i < done.size(); i++) { RapidoidConnection conn = done.get(i); if (conn.key != null && conn.key.isValid()) { conn.key.interestOps(SelectionKey.OP_WRITE); } } done.clear(); } }
private void dispose(Selector localSelector, LinkedBlockingQueue localSelectorTasks) { Assert.eval(Thread.currentThread() == this); if (localSelector != null) { for (Object element : localSelector.keys()) { try { SelectionKey key = (SelectionKey) element; cleanupChannel(key.channel(), null); } catch (Exception e) { logger.warn("Exception trying to close channel", e); } } try { localSelector.close(); } catch (Exception e) { if ((Os.isMac()) && (Os.isUnix()) && (e.getMessage().equals("Bad file descriptor"))) { // I can't find a specific bug about this, but I also can't seem to prevent the // exception on the Mac. // So just logging this as warning. logger.warn("Exception trying to close selector: " + e.getMessage()); } else { logger.error("Exception trying to close selector", 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 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); } }
private void doConnect(SelectionKey key) { SocketChannel sc = (SocketChannel) key.channel(); TCConnectionImpl conn = (TCConnectionImpl) key.attachment(); try { if (sc.finishConnect()) { sc.register(selector, SelectionKey.OP_READ, conn); conn.finishConnect(); } else { String errMsg = "finishConnect() returned false, but no exception thrown"; if (logger.isInfoEnabled()) { logger.info(errMsg); } conn.fireErrorEvent(new Exception(errMsg), null); } } catch (IOException ioe) { if (logger.isInfoEnabled()) { logger.info("IOException attempting to finish socket connection", ioe); } conn.fireErrorEvent(ioe, null); } }
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 { } } } }
/** Немедленно выключает интересуемое действие OP_READ */ protected void disableReadInterest() { try { _selectionKey.interestOps(_selectionKey.interestOps() & ~SelectionKey.OP_READ); } catch (CancelledKeyException e) { // ignore } }
@Override protected SelectChannelEndPoint newEndPoint( SocketChannel channel, SelectSet selectSet, SelectionKey key) throws IOException { // We're connected, cancel the connect timeout Timeout.Task connectTimeout = _connectingChannels.remove(channel); if (connectTimeout != null) connectTimeout.cancel(); if (LOG.isDebugEnabled()) LOG.debug("Channels with connection pending: {}", _connectingChannels.size()); // key should have destination at this point (will be replaced by endpoint after this call) HttpDestination dest = (HttpDestination) key.attachment(); SelectChannelEndPoint scep = new SelectChannelEndPoint(channel, selectSet, key, (int) _httpClient.getIdleTimeout()); AsyncEndPoint ep = scep; if (dest.isSecure()) { LOG.debug("secure to {}, proxied={}", channel, dest.isProxied()); ep = new UpgradableEndPoint(ep, newSslEngine(channel)); } AsyncConnection connection = selectSet.getManager().newConnection(channel, ep, key.attachment()); ep.setConnection(connection); AbstractHttpConnection httpConnection = (AbstractHttpConnection) connection; httpConnection.setDestination(dest); if (dest.isSecure() && !dest.isProxied()) ((UpgradableEndPoint) ep).upgrade(); dest.onNewConnection(httpConnection); return scep; }
@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); } }
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()); } }
// 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 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); } } }
public void registerInterestOps(EventHandler eventHandler) { if (orb.transportDebugFlag) { dprint(".registerInterestOps:-> " + eventHandler); } SelectionKey selectionKey = eventHandler.getSelectionKey(); if (selectionKey.isValid()) { int ehOps = eventHandler.getInterestOps(); SelectionKeyAndOp keyAndOp = new SelectionKeyAndOp(selectionKey, ehOps); synchronized (interestOpsList) { interestOpsList.add(keyAndOp); } // tell Selector Thread there's an update to a SelectorKey's Ops selector.wakeup(); } else { wrapper.selectionKeyInvalid(eventHandler.toString()); if (orb.transportDebugFlag) { dprint(".registerInterestOps: EventHandler SelectionKey not valid " + eventHandler); } } if (orb.transportDebugFlag) { dprint(".registerInterestOps:<- "); } }
/** {@inheritDoc} */ public SelectableChannel acceptWithoutRegistration(SelectionKey key) throws IOException { boolean isAccepted; int retryNum = 0; do { try { isAccepted = true; return ((ServerSocketChannel) key.channel()).accept(); } catch (IOException ex) { if (!key.isValid()) throw ex; isAccepted = false; try { // Let's try to recover here from too many open file Thread.sleep(1000); } catch (InterruptedException ex1) { throw new IOException(ex1.getMessage()); } logger.log( Level.WARNING, LogMessages.WARNING_GRIZZLY_TCPSELECTOR_HANDLER_ACCEPTCHANNEL_EXCEPTION(), ex); } } while (!isAccepted && retryNum++ < maxAcceptRetries); throw new IOException("Accept retries exceeded"); }
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 handleAccept(SelectionKey key) throws IOException { ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel(); SocketChannel socketChannel = serverSocketChannel.accept(); log.info("Server: accept client socket " + socketChannel); socketChannel.configureBlocking(false); socketChannel.register(key.selector(), SelectionKey.OP_READ); }
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(); } }