outgoing=writer.createSocket(local, remote, remote_port, hb_interval);
outgoing=timed_writer.createSocket(local, remote, remote_port, interval);
	public void run() {	    long  diff=0, curr_time=0, num_missed_hbs=0;	    	    if(trace) System.out.println("heartbeat to " + remote + ':' + remote_port + " started");	    while(!stop_hb) {		if(established) {  // send heartbeats		    // 1. Send heartbeat (use timed write)		    if(outstream != null) {			try {			    writer.write(outstream, HB_PACKET, 1500);			    Thread.sleep(hb_interval);			}			catch(Exception io_ex) {       // IOException and TimedWriter.Timeout			    closeOutgoingConnection(); // sets established to false			    continue;			}		    }		    else {			established=false;			continue;		    }			     		    // 2. If time of last HB received > timeout --> close connection		    curr_time=System.currentTimeMillis();		    diff=curr_time - last_hb;		    if(curr_time - last_hb > hb_interval) {			num_missed_hbs=(curr_time - last_hb) / hb_interval;			if(receiver != null)			    receiver.missedHeartbeat(local, local_port, remote, remote_port, (int)num_missed_hbs);			missed_hb=true;		    }		    if(diff >= timeout) {			if(trace) System.out.println("###### Link.Heartbeat.run(): no heartbeat receveived for " + 						     diff + " msecs. Closing connections. #####");			closeConnections(); // close both incoming *and* outgoing connections		    }		}		else {    // try to establish connection		    synchronized(outgoing_mutex) { // serialize access with createOutgoingConnection()			if(established) {			    continue;			}						try {			    outgoing=writer.createSocket(local, remote, remote_port, hb_interval);			    outstream=new DataOutputStream(outgoing.getOutputStream());			    if(receiver != null) receiver.linkUp(local, local_port, remote, remote_port);			    established=true;			    if(trace) System.out.println("-- CREATE (CE): " + printSocket(outgoing));			    continue;			}			catch(InterruptedException interrupted_ex) {			    continue;			}			catch(Exception ex) {         // IOException, TimedWriter.Timeout			    Util.sleep(hb_interval);  // returns when done or interrupted			}		    }		}	    }	    if(trace) System.out.println("heartbeat to " + remote + ':' + remote_port + " stopped");	    thread=null;	}