您的位置:首页 > 理论基础 > 计算机网络

golang tcp heartbeat

2016-03-20 18:01 423 查看
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
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: