@Override
	public void run() {
		while (this.isRunning) {
			if (!this.node.getNodeTable().isEmpty()) {
				Node n = this.node.picRandomEntry();
				try {

					// open a connection to a random node in the node table, send it a request for its node table, receive its node table, and merge
					// them together
					this.sock = new Socket(n.getIp(), n.getPort());

					this.objOut = new ObjectOutputStream(this.sock.getOutputStream());
					this.objIn = new ObjectInputStream(this.sock.getInputStream());
					this.objOut.writeObject(tableRequest());
					this.objOut.flush();
					MessageObject message = (MessageObject) this.objIn.readObject();
					if (message.getData() instanceof Set<?>) {
						Set<Node> remoteTable = (Set<Node>) message.getData();
						this.node.mergeLists(remoteTable);
					}
					closeConnection();
					Log.logMsg("Current Table of " + this.node.getSelf().getName() + ": " + this.node.getNodeTable());
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
				} catch (UnknownHostException e1) {
					this.node.removeEntry(n);
					e1.printStackTrace();
				} catch (IOException e1) {
					this.node.removeEntry(n);
					Log.logErr(n.getPort() + " refused connection " + this.node.getSelf().getPort());
				}
			}
			try {
				// sleep for a pre set interval
				Thread.sleep(this.interval);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}