code: public BindRequest connectAndOutbind(String host, int port, OutbindParameter outbindParameter, long timeout)
        throws IOException {
      logger.debug("Connect and bind to {} port {}", host, port);
      if (getSessionState() != SessionState.CLOSED) {
        throw new IOException("Session state is not closed");
      }
  
      conn = connFactory.createConnection(host, port);
      logger.info("Connected to {}", conn.getInetAddress());
  
      conn.setSoTimeout(getEnquireLinkTimer());
  
      sessionContext.open();
      try {
        in = new DataInputStream(conn.getInputStream());
        out = conn.getOutputStream();
  
        pduReaderWorker = new PDUReaderWorker();
        pduReaderWorker.start();
        sendOutbind(outbindParameter.getSystemId(), outbindParameter.getPassword());
      }
      catch (IOException e) {
        logger.error("IO error occurred", e);
        close();
        throw e;
      }
  
      try {
        BindRequest bindRequest = waitForBind(timeout);
  
        logger.info("Start enquireLinkSender");
        enquireLinkSender = new EnquireLinkSender();
        enquireLinkSender.start();
  
        return bindRequest;
      }
      catch (IllegalStateException e) {
        String message = "System error";
        logger.error(message, e);
        close();
        throw new IOException(message + ": " + e.getMessage(), e);
      }
      catch (TimeoutException e) {
        String message = "Waiting bind response take time too long";
        logger.error(message, e);
        throw new IOException(message + ": " + e.getMessage(), e);
      }
    }
docs: Open connection and outbind immediately.
  
  @param host             is the ESME host address.
  @param port             is the ESME listen port.
  @param outbindParameter is the bind parameters.
  @param timeout          is the timeout.
  @return the SMSC system id.
  @throws IOException if there is an IO error found.