void startClose() { if (isOpen()) { finishClose(); // Call "close()" before "onDisconnect()" // to avoid recursive "disconnect()". connection.onDisconnect(); } }
@Override public void setBufferSize(int bufferSize) { boolean blocked = Client.this.bufferSize == 0; boolean toBlock = bufferSize <= 0; Client.this.bufferSize = Math.max(0, Math.min(bufferSize, Connection.MAX_BUFFER_SIZE)); if ((blocked ^ toBlock) && !resolving && isOpen()) { // may be called before resolve interestOps(); } }
void register(Selector selector) throws IOException { if ((interestOps & SelectionKey.OP_CONNECT) != 0) { ((Client) att).startClose(); // Log.w("Removed a Connection-Pending Channel, interestOps = " + interestOps); return; } // Client may be closed by closing of Connection-Pending Channel if (att instanceof Client && !((Client) att).isOpen()) { return; } att.selectionKey = channel.register(selector, interestOps, att); } }
throw new RuntimeException(e); Client client = new Client(server.serverConnection.get()); client.socketChannel = socketChannel; client.add(selector, SelectionKey.OP_READ); client.finishConnect(); continue; client.startClose(); client.write(); } else if (key.isConnectable() && client.socketChannel.finishConnect()) { client.finishConnect(); if (client.isBusy()) { client.write(); client.startClose();
void write() throws IOException { int len = queue.length(); int fromLen = len; while (len > 0) { int bytesWritten = socketChannel.write(ByteBuffer.wrap(queue.array(), queue.offset(), len)); if (bytesWritten == 0) { unblock(len, fromLen); return; } len = queue.remove(bytesWritten).length(); } unblock(len, fromLen); if (status == STATUS_DISCONNECTING) { finishClose(); } else { status = STATUS_IDLE; interestOps(); } }
public void connect(Connection connection, InetSocketAddress socketAddress) throws IOException { Client client = new Client(connection); client.startConnect(); if (!socketAddress.isUnresolved()) { client.connect(selector, socketAddress); return; if (host.indexOf(':') >= 0 || !hostName.matcher(host).find()) { client.connect(selector, new InetSocketAddress(InetAddress.getByName(host), port)); return; invokeLater(() -> { try { client.connect(selector, new InetSocketAddress(addr, port)); } catch (IOException e) {
void write(byte[] b, int off, int len) { if (status != STATUS_IDLE) { int fromLen = queue.length(); block(queue.add(b, off, len).length(), fromLen); return; } int bytesWritten; try { bytesWritten = socketChannel.write(ByteBuffer.wrap(b, off, len)); } catch (IOException e) { startClose(); return; } if (len > bytesWritten) { int fromLen = queue.length(); block(queue.add(b, off + bytesWritten, len - bytesWritten).length(), fromLen); status = STATUS_BUSY; interestOps(); } }
/** * registers a {@link Client} and connects to a remote address * * @see ConnectorImpl#connect(Connection, String, int) * @throws IOException may throw "Network is unreachable" or "Protocol family unavailable", * and then socketChannel will be closed, and selectionKey will not be created */ void connect(Selector selector, InetSocketAddress socketAddress) throws IOException { resolving = false; try { socketChannel = SocketChannel.open(); socketChannel.configureBlocking(false); socketChannel.socket().setTcpNoDelay(true); } catch (IOException e) { throw new RuntimeException(e); } try { socketChannel.connect(socketAddress); add(selector, SelectionKey.OP_CONNECT); } catch (IOException e) { // May throw "Network is unreachable" or "Protocol family unavailable", // and then socketChannel will be closed, and selectionKey will not be created closeChannel(); throw e; } }
@Override public void disconnect() { if (status == STATUS_IDLE) { // must be resolved finishClose(); } else if (status == STATUS_BUSY) { status = STATUS_DISCONNECTING; } } });