// initialize data hash table servers
  // read server addresses from file and initialize the servers
  private void initServers() {

    try {
      java.net.URL path = ClassLoader.getSystemResource(clientSettingFile);
      FileReader fr = new FileReader(path.getFile());
      BufferedReader br = new BufferedReader(fr);
      try {
        String[] portMap = br.readLine().split(",");
        mServerCount = portMap.length;
        mPortMap = new int[mServerCount];
        for (int i = 0; i < mServerCount; i++) {
          mPortMap[i] = Integer.parseInt(portMap[i]);
        }
      } catch (IOException e) {
        e.printStackTrace();
        System.exit(-1);
      }
    } catch (FileNotFoundException e2) {
      e2.printStackTrace();
      System.exit(-1);
    }

    mDhtServerArray = new IDistributedHashTable[mServerCount];
    for (int i = 0; i < mServerCount; i++) {
      try {
        mDhtServerArray[i] =
            (IDistributedHashTable)
                Naming.lookup("rmi://localhost:" + mPortMap[i] + "/DistributedHashTable");
        appendOutput("server: " + (i + 1) + " is connected");
      } catch (Exception e) {
        appendOutput("initServers: " + (i + 1) + " " + e.getMessage());
      }
    }
  }
 // send a count request to a server
 // 1 < key < max key number
 // server: id of server to count the number of entities
 private void sendCountRequest(int server) {
   try {
     if (mDhtServerArray[server - 1] != null) {
       int n = mDhtServerArray[server - 1].count();
       appendOutput("Count machine " + server + " is " + n);
     } else appendOutput("sendCountRequest: server " + server + " is not initialized");
   } catch (Exception e) {
     appendOutput("sendCountRequest: " + server + e.getMessage());
   }
 }
 // send a purge request to a server
 // 1 < key < max key number
 // server: id of server to purge data
 private void sendPurgeRequest() {
   for (int i = 0; i < mServerCount; i++) {
     if (mDhtServerArray[i] != null) {
       try {
         mDhtServerArray[i].purge();
         appendOutput("purge: machine " + (i + 1));
       } catch (Exception e1) {
         appendOutput("purge server " + (i + 1) + " " + e1.getMessage());
       }
     } else appendOutput("purge server " + (i + 1) + " is not initialized");
   }
 }
 // send a delete request to a server
 // 1 < key < max key number
 // server: id of server to delete the key
 private void sendDeleteRequest(int key, int server) {
   IQueryRequest queryReq = new QueryRequest(mRequestId++, server, key);
   try {
     if (mDhtServerArray[server - 1] != null) {
       UnicastRemoteObject.exportObject(queryReq);
       mDhtServerArray[server - 1].delete(queryReq);
       appendOutput("DHT Server:\n" + queryReq.getMessage());
     } else appendOutput("sendDeleteRequest: server " + server + " is not initialized");
   } catch (Exception e) {
     appendOutput("sendDeleteRequest: " + server + e.getMessage());
   }
 }
 // send an insert request to a server
 // 1 < key < max key number
 // server: id of server to insert the key
 private void sendInsertRequest(int key, Object value, int server) {
   IInsertRequest insReq = new InsertRequest(mRequestId++, server, key, value);
   try {
     if (mDhtServerArray[server - 1] != null) {
       UnicastRemoteObject.exportObject(insReq);
       mDhtServerArray[server - 1].insert(insReq);
       appendOutput("DHT Server:\n" + insReq.getMessage());
     } else appendOutput("sendInsertRequest: server " + server + " is not initialized");
   } catch (Exception e) {
     appendOutput("sendInsertRequest: " + server + e.getMessage());
   }
 }
 // send a lookup request to a server
 // 1 < key < max key number
 // server: id of server to lookup the key
 private void sendLookupRequest(int key, int server) {
   IQueryRequest queryReq = new QueryRequest(mRequestId++, server, key);
   try {
     if (mDhtServerArray[server - 1] != null) {
       UnicastRemoteObject.exportObject(queryReq);
       String value = (String) mDhtServerArray[server - 1].lookup(queryReq);
       appendOutput(
           "DHT Server:\n" + queryReq.getMessage() + "\nDHT Client:\nlookup value is " + value);
     } else appendOutput("sendLookupRequest: server " + server + " is not initialized");
   } catch (Exception e) {
     appendOutput("sendLookupRequest: " + server + e.getMessage());
   }
 }
  public static void main(String[] args) {
    String clientSettingFile = "";
    GetOpt getopt = new GetOpt(args, "f:");
    try {
      int c;
      while ((c = getopt.getNextOption()) != -1) {
        switch (c) {
          case 'f':
            clientSettingFile = getopt.getOptionArg();
            break;
        }
      }
    } catch (Exception e1) {
      e1.printStackTrace();
    }
    final DHTInteractiveClient dhtClient = new DHTInteractiveClient(clientSettingFile);

    javax.swing.SwingUtilities.invokeLater(
        new Runnable() {
          public void run() {
            dhtClient.createAndShowGUI();
          }
        });
  }