func IsPublicFrameType(ft uint32) bool {
	return frameconn.IsPublicFrameType(ft) && (0xf<<24)&ft == 0
}
The 4 MSBs of ft are reserved for frameconn, we reserve the next 4 MSB for us.
package heartbeatconn
import (
	"fmt"
	"net"
	"sync/atomic"
	"time"
	"github.com/zrepl/zrepl/rpc/dataconn/frameconn"
	"github.com/zrepl/zrepl/rpc/dataconn/timeoutconn"
)
type Conn struct {
	state                 state
	fc                    *frameconn.Conn
	sendInterval, timeout time.Duration
	stopSend              chan struct{}
	lastFrameSent         atomic.Value  
}
type HeartbeatTimeout struct{}
func (e HeartbeatTimeout) Error() string {
	return "heartbeat timeout"
}
func (e HeartbeatTimeout) Temporary() bool { return true }
func (e HeartbeatTimeout) Timeout() bool { return true }
var _ net.Error = HeartbeatTimeout{}
type state = int32
const (
	stateInitial state = 0
	stateClosed  state = 2
)
const (
	heartbeat uint32 = 1 << 24
)