获取远程端的地址信息，包括host和端口<br>
null表示channel为null或者远程主机未连接

@param channel {@link AsynchronousSocketChannel}
@return 远程端的地址信息，包括host和端口，null表示channel为null或者远程主机未连接
427649
public static SocketAddress getRemoteAddress(AsynchronousSocketChannel channel) {
		try {
			return (null == channel) ? null : channel.getRemoteAddress();
		} catch (ClosedChannelException e) {
			// Channel未打开或已关闭，返回null表示未连接
			return null;
		} catch (IOException e) {
			throw new IORuntimeException(e);
		}
	}
1307940
Channel getChannel() throws ConnectionFailedException {
        Channel ch = channel.get();
        if (ch == null) {
            throw new ConnectionFailedException("Connection to " + connectionName + " is not established.");
        }
        return ch;
    }
743383
final public SelectionKey getKey(SocketChannel channel) {
        if (null == channel) {
            return null;
        }
        return channel.keyFor(this.selector);
    }
1306618
private EventChannelStruct getEventChannelStruct(String channelName) {
        if (channel_map.containsKey(channelName)) {
            return channel_map.get(channelName);
        }
        //  Check with other TangoHosts using possibleTangoHosts as header
        int index = channelName.indexOf("//");
        if (index>0) {
            index = channelName.indexOf('/', index+2); //  "//".length()
            for (String possibleTangoHost : possibleTangoHosts) {
                String key = possibleTangoHost + channelName.substring(index);
                if (channel_map.containsKey(key))
                    return channel_map.get(key);
            }
        }
        return null;
    }
364220
@Override
    public void processConnect(WebSocketChannel channel, WSURI location, String[] protocols) {
        LOG.entering(CLASS_NAME, "connect", channel);
        WebSocketCompositeChannel compositeChannel = (WebSocketCompositeChannel)channel;
        
        if (compositeChannel.readyState != ReadyState.CLOSED) {
            LOG.warning("Attempt to reconnect an existing open WebSocket to a different location");
            throw new IllegalStateException("Attempt to reconnect an existing open WebSocket to a different location");
        }

        compositeChannel.readyState = ReadyState.CONNECTING;
        compositeChannel.requestedProtocols = protocols;
        
        String scheme = compositeChannel.getCompositeScheme();
        if (scheme.indexOf(":") >= 0) {
            // qualified scheme: e.g. "java:wse" 
            WebSocketStrategy strategy = strategyMap.get(scheme);
            if (strategy == null) {
                throw new IllegalArgumentException("Invalid connection scheme: "+scheme);
            }
            
            LOG.finest("Turning off fallback since the URL is prefixed with java:");
            compositeChannel.connectionStrategies.add(scheme);
        }
        else {
            String[] connectionStrategies = strategyChoices.get(scheme);
            if (connectionStrategies != null) {
                for (String each : connectionStrategies) {
                    compositeChannel.connectionStrategies.add(each);
                }
            }
            else {
                throw new IllegalArgumentException("Invalid connection scheme: "+scheme);
            }
        }

        fallbackNext(compositeChannel, null);
    }
1025407
static ConnectionInfo newConnectionInfo(Channel c) {
		SocketChannel channel = (SocketChannel) c; 
		InetSocketAddress hostAddress = channel.localAddress();
		InetSocketAddress remoteAddress = getRemoteAddress(channel);
		String scheme = channel.pipeline().get(SslHandler.class) != null ? "https" : "http";
		return new ConnectionInfo(hostAddress, remoteAddress, scheme);
	}
1319607
public Set<WebSocketChannel> getChannels(String uri) {
        Objects.requireNonNull(uri, Required.URI.toString());

        final Set<WebSocketChannel> channels = this.cache.get(Default.WSS_CACHE_PREFIX.toString() + uri);

        return (channels == null) ? new HashSet<>() : channels;
    }
507954
private synchronized void createChannel(String channel) {
        if (!channelExists(channel)) {
            Queue queue = new Queue(channel, true, false, true);
            admin.declareQueue(queue);
            Binding binding = new Binding(channel, DestinationType.QUEUE, exchange.getName(), channel + ".#", null);
            admin.declareBinding(binding);
        }
    }
172404
private SocketChannel connectToHost(SocketAddress hostAddr)
            throws IOException
    {
        SocketChannel socket = null;
        while (socket == null) {
            try {
                socket = SocketChannel.open(hostAddr);
            }
            catch (java.net.ConnectException e) {
                LOG.warn("Joining host failed: " + e.getMessage() + " retrying..");
                try {
                    Thread.sleep(250); //  milliseconds
                }
                catch (InterruptedException dontcare) {}
            }
        }
        return socket;
    }
153858
public AioServer init(InetSocketAddress address) {
		try {
			this.group = AsynchronousChannelGroup.withFixedThreadPool(//
					config.getThreadPoolSize(), // 默认线程池大小
					ThreadFactoryBuilder.create().setNamePrefix("Hutool-socket-").build()//
			);
			this.channel = AsynchronousServerSocketChannel.open(group).bind(address);
		} catch (IOException e) {
			throw new IORuntimeException(e);
		}
		return this;
	}
627104
public Channel getChannel(int channelId) {
        Channel channel = channels.putIfAbsent(channelId, new Channel(this, channelId));
        if (channel == null) {
            channel = channels.get(channelId);
        }
        return channel;
    }
191081
@CheckForNull
    public final VirtualChannel getChannel() {
        Computer c = toComputer();
        return c==null ? null : c.getChannel();
    }
1058095
public static final ChannelInitializer<Channel> httpClient(
      final SimpleChannelInboundHandler<HttpResponse> handler) {
    return new ChannelInitializer<Channel>() {

      @Override
      protected void initChannel(Channel channel) throws Exception {
        ChannelPipeline pipeline = channel.pipeline();
        pipeline.addLast("httpCodec", new HttpClientCodec());
        pipeline.addLast("aggregator", new HttpObjectAggregator(10 * 1024 * 1024));
        pipeline.addLast("httpClientHandler", handler);
      }
    };
  }
726472
@Override
  public InetAddress addressRemote()
  {
    SocketChannel s = _channel;
    
    if (s != null) {
      try {
        InetSocketAddress addr = (InetSocketAddress) s.getRemoteAddress();
        
        return addr.getAddress();
      } catch (IOException e) {
        throw new RuntimeException(e);
      }
    }
    else {
      return null;
    }
  }
228492
@Override
    public void connectAsynch(Object address) {
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
            Tr.entry(tc, "connectAsynch, vc=" + getVCHash());
        }
        // Determine if this is a redundant connect.
        if (connected) {
            handleRedundantConnect();
        }
        this.targetAddress = (TCPConnectRequestContext) address;
        // Nothing specific to SSL on connect. Pass through.
        ((OutboundConnectionLink) getDeviceLink()).connectAsynch(address);
        // The SSL handshake will happen in the ready method path.
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
            Tr.exit(tc, "connectAsynch");
        }
    }
161344
InputStream readChannel(int channel)
        throws IOException
    {
        while (!isClosed) {
            if (inputReady[channel]) {
                inputReady[channel] = false;
                return is;
            }

            boolean canRead = false;
            synchronized (READ_LOCK) {
                if (!isReadLocked) {
                    isReadLocked = true;
                    canRead = true;
                }
                else {
                    try {
                        READ_LOCK.wait(5000);
                    } catch (Exception e) {
                    }
                }
            }

            if (canRead) {
                try {
                    readData();
                } catch (IOException e) {
                    close();
                }
            }
        }

        return null;
    }
331822
@SuppressWarnings("unused")
    public synchronized Channel findOrCreateChannel(ChannelData channelData) throws ChannelException {
        String channelName = channelData.getName();
        Channel ret = this.existingChannels.get(channelName);
        if (ret == null) {
            // Create the new channel with the input configuration
            if (null != this.globalBufferSize) {
                // if the factory setting exists, see if the channel overrides it
                // otherwise apply it now
                Map<Object, Object> props = channelData.getPropertyBag();
                if (!props.containsKey(PROP_BUFFERSIZE)) {
                    props.put(PROP_BUFFERSIZE, this.globalBufferSize);
                }
            }
            ret = new HttpDispatcherChannel(channelData, this);
            this.existingChannels.put(channelName, ret);
        }
        return ret;
    }