@Override
  public void open() throws IOException {
    if (channel == null) {
      channel = SocketChannel.open();
      channel.configureBlocking(false);

      if (maxSendBufferSize > 0) {
        channel.setOption(StandardSocketOptions.SO_SNDBUF, maxSendBufferSize);
        final int actualSendBufSize = channel.getOption(StandardSocketOptions.SO_SNDBUF);
        if (actualSendBufSize < maxSendBufferSize) {
          logger.warn(
              "Attempted to set Socket Send Buffer Size to "
                  + maxSendBufferSize
                  + " bytes but could only set to "
                  + actualSendBufSize
                  + "bytes. You may want to "
                  + "consider changing the Operating System's maximum receive buffer");
        }
      }
    }

    if (!channel.isConnected()) {
      final long startTime = System.currentTimeMillis();
      final InetSocketAddress socketAddress =
          new InetSocketAddress(InetAddress.getByName(host), port);

      if (!channel.connect(socketAddress)) {
        while (!channel.finishConnect()) {
          if (System.currentTimeMillis() > startTime + timeout) {
            throw new SocketTimeoutException("Timed out connecting to " + host + ":" + port);
          }

          try {
            Thread.sleep(50L);
          } catch (final InterruptedException e) {
          }
        }
      }

      socketChannelOutput = new SocketChannelOutputStream(channel);
      socketChannelOutput.setTimeout(timeout);
    }
  }
 @Override
 public <T> T getOption(SocketOption<T> name) throws IOException {
   return socketChannel.getOption(name);
 }