golang tcp heartbeat

来源:互联网 发布:知即墨下载安装 编辑:程序博客网 时间:2024/06/05 08:20
package mainimport "log"import "time"const TIMEOUT_NS = int64(30e9) // 30 secondstype Msg struct {Header uint8 // == 1SeqNo  uint32Data   uint8 // the real case is complex}type Reply struct {Header uint8 // == 2SeqNo  uint32Status uint8}type AskHeartBeat struct {Header uint8 // == 4SeqNo  uint32}type ReplyHeartBeat struct {Header uint8 // == 4SeqNo  uint32}type TCPCh chan interface{} // simulate TCPtype CmdCh chan uint8       // 0:Quit 1:ask HBvar gLastHBTime int64 // heartbeat timefunc Sender(tcp TCPCh, cS2R, cR2S, cQuit CmdCh) {var cmd uint8seq := uint32(1)n := 10 // send 10 msgsL_LOOP:for {select {case cmd = <-cR2S:if cmd == 0 {break L_LOOP}if cmd == 1 {gLastHBTime = time.Nanoseconds()hbr := ReplyHeartBeat{5, seq}seq++log.Println("S", hbr)tcp <- hbr}default:now := time.Nanoseconds()if now-gLastHBTime > TIMEOUT_NS {hb := &AskHeartBeat{4, seq}log.Println("S", hb)tcp <- hbseq++}gLastHBTime = nowif n < 0 {time.Sleep(20e9) // wait replycS2R <- 0        // ask to quitbreak L_LOOP}n--m := &Msg{1, seq, 0}seq++log.Println("S", m)tcp <- m}}cQuit <- 0}func Receiver(tcp TCPCh, cS2R, cR2S, cQuit CmdCh) {var v interface{}var cmd uint8lastSeq := uint32(0)L_LOOP:for {select {case v = <-tcp:gLastHBTime = time.Nanoseconds()switch v.(type) {case Reply:r := v.(Reply)if lastSeq+1 != r.SeqNo {cR2S <- 0 // force sender quit}log.Println("R", r)case AskHeartBeat:r := v.(AskHeartBeat)if lastSeq+1 != r.SeqNo {cR2S <- 0 // force sender quit}log.Println("R", r)cR2S <- 1 // request send ReplyHeartBeatcase ReplyHeartBeat:r := v.(ReplyHeartBeat)if lastSeq+1 != r.SeqNo {cR2S <- 1 // force sender quit}log.Println("R", r)}case cmd = <-cS2R:if cmd == 0 {break L_LOOP}}}cQuit <- 0}func main() {cTCP := make(chan interface{}, 1024)cQuit := make(chan uint8, 2)cS2R := make(chan uint8)cR2S := make(chan uint8)gLastHBTime = time.Nanoseconds()go Sender(cTCP, cS2R, cR2S, cQuit)go Receiver(cTCP, cS2R, cR2S, cQuit)<-cQuit<-cQuit}

0 0