golang tcp heartbeat

package main

import "log"
import "time"

const TIMEOUT_NS = int64(30e9) // 30 seconds

type Msg struct {
	Header uint8 // == 1
	SeqNo  uint32
	Data   uint8 // the real case is complex
}
type Reply struct {
	Header uint8 // == 2
	SeqNo  uint32
	Status uint8
}
type AskHeartBeat struct {
	Header uint8 // == 4
	SeqNo  uint32
}
type ReplyHeartBeat struct {
	Header uint8 // == 4
	SeqNo  uint32
}
type TCPCh chan interface{} // simulate TCP
type CmdCh chan uint8       // 0:Quit 1:ask HB

var gLastHBTime int64 // heartbeat time

func Sender(tcp TCPCh, cS2R, cR2S, cQuit CmdCh) {
	var cmd uint8
	seq := uint32(1)
	n := 10 // send 10 msgs

L_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 <- hb
				seq++
			}
			gLastHBTime = now
			if n < 0 {
				time.Sleep(20e9) // wait reply
				cS2R <- 0        // ask to quit
				break 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 uint8

	lastSeq := 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 ReplyHeartBeat
			case 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
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值