/**
   * Initialize a server socket for communicating with the client.
   *
   * @param iHostPortRange
   * @param iHostName
   */
  private void listen(
      final String iHostName, final String iHostPortRange, final String iProtocolName) {
    final int[] ports = getPorts(iHostPortRange);

    for (int port : ports) {
      inboundAddr = new InetSocketAddress(iHostName, port);
      try {
        serverSocket = socketFactory.createServerSocket(port, 0, InetAddress.getByName(iHostName));

        if (serverSocket.isBound()) {
          OLogManager.instance()
              .info(
                  this,
                  "Listening "
                      + iProtocolName
                      + " connections on "
                      + inboundAddr.getAddress().getHostAddress()
                      + ":"
                      + inboundAddr.getPort()
                      + " (protocol v."
                      + protocolVersion
                      + ", socket="
                      + socketFactory.getName()
                      + ")");
          return;
        }
      } catch (BindException be) {
        OLogManager.instance()
            .info(this, "Port %s:%d busy, trying the next available...", iHostName, port);
      } catch (SocketException se) {
        OLogManager.instance().error(this, "Unable to create socket", se);
        ShutdownHelper.shutdown(1);
      } catch (IOException ioe) {
        OLogManager.instance().error(this, "Unable to read data from an open socket", ioe);
        System.err.println("Unable to read data from an open socket.");
        ShutdownHelper.shutdown(1);
      }
    }

    OLogManager.instance()
        .error(
            this,
            "Unable to listen for connections using the configured ports '%s' on host '%s'",
            iHostPortRange,
            iHostName);
    ShutdownHelper.shutdown(1);
  }
  public OServerNetworkListener(
      final OServer iServer,
      final OServerSocketFactory iSocketFactory,
      final String iHostName,
      final String iHostPortRange,
      final String iProtocolName,
      final Class<? extends ONetworkProtocol> iProtocol,
      final OServerParameterConfiguration[] iParameters,
      final OServerCommandConfiguration[] iCommands) {
    super(
        Orient.instance().getThreadGroup(),
        "OrientDB " + iProtocol.getSimpleName() + " listen at " + iHostName + ":" + iHostPortRange);
    server = iServer;

    socketFactory = iSocketFactory == null ? OServerSocketFactory.getDefault() : iSocketFactory;

    // DETERMINE THE PROTOCOL VERSION BY CREATING A NEW ONE AND THEN THROW IT AWAY
    // TODO: CREATE PROTOCOL FACTORIES INSTEAD
    try {
      protocolVersion = iProtocol.newInstance().getVersion();
    } catch (Exception e) {
      OLogManager.instance()
          .error(
              this,
              "Error on reading protocol version for %s",
              e,
              ONetworkProtocolException.class,
              iProtocol);
    }

    listen(iHostName, iHostPortRange, iProtocolName);
    protocolType = iProtocol;

    readParameters(iServer.getContextConfiguration(), iParameters);

    if (iCommands != null) {
      for (int i = 0; i < iCommands.length; ++i) {
        if (iCommands[i].stateful)
          // SAVE STATEFUL COMMAND CFG
          registerStatefulCommand(iCommands[i]);
        else
          // EARLY CREATE STATELESS COMMAND
          registerStatelessCommand(OServerNetworkListener.createCommand(server, iCommands[i]));
      }
    }

    start();
  }