/**
   * sendUserID: send id to the user print writer
   *
   * @return: the response
   */
  protected String sendUserID() throws Exception {

    assert _userOut != null;
    String output = ProtocolConstants.PACK_STR_USR_HEAD + " " + _server.getID();
    String reply = NetComm.sendAndRecv(output, _userOut, _userIn);
    return reply;
  }
  /** listen: start to listen if there is any clients connected */
  public void listen() {

    // Firstly spawn a new thread and then the main thread
    // also start listening
    _userNet = new DropboxFileServerUserNet(_server, _userOut, _userIn, _userSock);
    _userNet.start();

    /* Use main thread, cannot be stopped */
    while (_sock != null && !_sock.isClosed()) {
      try {
        String line = NetComm.receive(_in);
        _dlog(line);
        parse(line);
      } catch (Exception e) {
        if (!_server.noException()) {
          _elog(e.toString());
        }
        break;
        // Break the loop
      }
    }

    /* Clear */
    // Close main thread
    clear();
    // Cancel the listening thread and retry
    _server.cancelListeningThread();
    /* Also cancel all of the syncers */
    _server.cancelSyncers();
    // Retry after
    try {

      _log(
          "The connection to master is broken,"
              + " reset everything and retry connection after "
              + DropboxConstants.TRY_CONNECT_MILLIS
              + " milliseconds");

      Thread.sleep(DropboxConstants.TRY_CONNECT_MILLIS);

    } catch (InterruptedException e) {
      if (!_server.noException()) {
        _elog(e.toString());
      }
      if (_server.debugMode()) {
        e.printStackTrace();
      }
    }
    _server.run();

    clear();
    _log(_threadName + " is stopped");
  }
  /**
   * sendAll: send all of the information to the print writer
   *
   * @return: the response
   */
  protected String sendAll() throws Exception {

    assert _out != null;
    String output = _server.getID() + " " + _server.getPrio() + " " + _server.getMaxClientNum();
    Map<String, ClientNode> mp = _server.getClients();
    Iterator it = mp.entrySet().iterator();
    while (it.hasNext()) {
      Map.Entry pair = (Map.Entry) it.next();
      String name = (String) pair.getKey();
      ClientNode node = (ClientNode) pair.getValue();
      output += " " + name + " " + node.getPassword();
    }
    output = ProtocolConstants.PACK_STR_ID_HEAD + " " + output;
    String reply = NetComm.sendAndRecv(output, _out, _in);
    return reply;
  }
 /**
  * parse: parse the string and send response
  *
  * @param str: the given string
  */
 protected void parse(String str) {
   StringTokenizer st = new StringTokenizer(str);
   String tkn = st.nextToken();
   try {
     if (tkn.equals(ProtocolConstants.PACK_STR_HEARTBEAT_HEAD)) {
       _dlog("I got heartbeat");
       // Send back confirmation
       // TODO: add more story here
       NetComm.send(ProtocolConstants.PACK_STR_HEARTBEAT_HEAD, _out);
     } else if (tkn.equals(ProtocolConstants.PACK_STR_REQUEST_FS_HEAD)) {
       // TODO: add more story here
     } else {
       _elog("Invalid header, skip.");
     }
   } catch (Exception e) {
     if (!_server.noException()) {
       _elog(e.toString());
     }
     if (_server.debugMode()) {
       e.printStackTrace();
     }
   }
 }