public void run() {
		while(true){
			for (Map.Entry<Integer, String> peer : pingPeers.entrySet()) {
				try{
					// TODO add host name to the address and parse it here instead of hard code localhost
					int peerId = peer.getKey();
					int peerPort = Integer.parseInt(peer.getValue());
					FailureDetectorThread.handleMessage("Send PING to server : " + peerId  + " in port: " + peerPort  + ".");
					String ping = "PING from " + this.myId;
					DatagramSocket clientSocket = new DatagramSocket();
					// If no ACK after 1 second, then report failure 
					clientSocket.setSoTimeout(1000);
					InetAddress IPAddress = InetAddress.getByName("localhost");
					byte[] sendData = new byte[1024];
					byte[] receiveData = new byte[1024];
					sendData = ping.getBytes();
					DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, peerPort );
					
					try{
						clientSocket.send(sendPacket);
					}catch (SocketException e) {
						FailureDetectorThread.handleMessage("error sending PING to server " + peerId + ": " + e.getMessage());
					} 
					
					DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
					try{
						clientSocket.receive(receivePacket);
						String ack = new String(receivePacket.getData());
						FailureDetectorThread.handleMessage("ACK from server: " + ack);
					}
					catch(SocketTimeoutException timeout){
						synchronized(failedServer){
							FailureDetectorThread.handleMessage("Server " + peerId + " Failed.");
							failedServer.add(peerId);
						}
					}
					finally{
						if(clientSocket != null)
							clientSocket.close();
					}
				}catch (IOException e) {
					FailureDetectorThread.handleMessage("Send Thread: " + e.getMessage());
				}
			}
			// if there is at lease one failed server, try to reconstruct it. May be failed servers are back now
			if(failedServer.size() > 0){
				try {
					sleep(1000);
				} catch (InterruptedException e) {
					FailureDetectorThread.handleMessage("Send Thread: " + e.getMessage());
				}
				reconstructRing();
			}
				
			try {
				sleep(3000);
			} catch (InterruptedException e) {
				FailureDetectorThread.handleMessage("Send Thread: " + e.getMessage());
			}
		}
	}