@Override
    protected void process() throws IOException {
        int select = mSelector.select();
        if (select == 0) {
            return;
        }
        Set<SelectionKey> selectedKeys = mSelector.selectedKeys();
        if (selectedKeys == null) {
            return;
        }
        Iterator<SelectionKey> iterator = selectedKeys.iterator();
        while (iterator.hasNext()) {
            SelectionKey key = iterator.next();
            try {
                if (key.isValid()) {
                    if (key.isAcceptable()) {
                        onAccept();
                    } else {
                        Object attachment = key.attachment();
                        if (attachment instanceof NioCallback) {
                            NioCallback callback = (NioCallback) attachment;
                            try {
                                if (key.isConnectable()) {
                                    callback.onConnected();
                                } else if (key.isReadable()) {
                                    callback.onRead();
                                } else if (key.isWritable()) {
                                    callback.onWrite();
                                }
                            } catch (IOException e) {
                                NioTunnel tunnel = callback.getTunnel();
                                String ip = null;
                                InetAddress address = ((Socket)tunnel.socket()).getInetAddress();
                                if (address != null) {
                                    ip = address.getHostAddress();
                                }
                                if (!tunnel.isClosed()) {
                                    handleException(e, ip);
                                }
                                callback.onClosed();
                            }
                        }
                    }
                }
            } finally {
                iterator.remove();
            }

        }
    }
The TCP proxy server is a nio {@link ServerSocketChannel}, it listens the connections from
{@link VpnService} and forwards request packets to real remote server. This server uses
{@link TcpVATunnel} to bind {@link VirtualGateway} and {@link NioTunnel} together. Every TCP
connection has two channels: {@link TcpProxyTunnel} and {@link TcpRemoteTunnel}.
The {@link TcpProxyTunnel} is responsible for sending remote server response packets to VPN
service, and the {@link TcpRemoteTunnel} is responsible for communicating with remote server.

@author Megatron King
@since 2018-10-11 17:35
netbare-core/src/main/java/com/github/megatronking/netbare/proxy/TcpProxyServer.java