diff --git a/client.go b/client.go index 1deab02..e6c04d3 100644 --- a/client.go +++ b/client.go @@ -64,15 +64,18 @@ type Client struct { recvPacket uint64 sendPacketSize uint64 recvPacketSize uint64 - - sendHBPacket uint64 } type ClientConn struct { - ipaddr *net.UDPAddr - id string - activeTime time.Time - close bool + ipaddr *net.UDPAddr + id string + activeTime time.Time + close bool + recvPacket uint64 + avgRecvNum uint64 + avgRecvPacket uint64 + hbPacket uint64 + sendHBPacket uint64 } func (p *Client) Addr() string { @@ -124,14 +127,7 @@ func (p *Client) Run() { interval := time.NewTicker(time.Second) defer interval.Stop() - inter := 1000 - if p.hb > 0 { - inter := 1000 / p.hb - if inter <= 0 { - inter = 1 - } - } - intervalHB := time.NewTicker(time.Millisecond * (time.Duration)(inter)) + intervalHB := time.NewTicker(time.Millisecond * 10) defer intervalHB.Stop() for { @@ -140,6 +136,7 @@ func (p *Client) Run() { p.checkTimeoutConn() p.ping() p.showNet() + p.calcHB() case <-intervalHB.C: p.heartbeat() case r := <-recv: @@ -215,6 +212,7 @@ func (p *Client) processPacket(packet *Packet) { now := time.Now() clientConn.activeTime = now + clientConn.recvPacket++ _, err := p.listenConn.WriteToUDP(packet.data, addr) if err != nil { @@ -262,13 +260,12 @@ func (p *Client) ping() { } func (p *Client) showNet() { - fmt.Printf("send %dPacket/s %dKB/s recv %dPacket/s %dKB/s HB %d/s\n", - p.sendPacket, p.sendPacketSize/1024, p.recvPacket, p.recvPacketSize/1024, p.sendHBPacket) + fmt.Printf("send %dPacket/s %dKB/s recv %dPacket/s %dKB/s\n", + p.sendPacket, p.sendPacketSize/1024, p.recvPacket, p.recvPacketSize/1024) p.sendPacket = 0 p.recvPacket = 0 p.sendPacketSize = 0 p.recvPacketSize = 0 - p.sendHBPacket = 0 } func (p *Client) heartbeat() { @@ -276,13 +273,39 @@ func (p *Client) heartbeat() { if p.hb > 0 { for _, conn := range p.localIdToConnMap { - b := make([]byte, 4) - binary.BigEndian.PutUint32(b[:4], rand.Uint32()) - sendICMP(p.id, p.sequence, *p.conn, p.ipaddrServer, p.targetAddr, conn.id, (uint32)(HB), b, p.sproto, p.rproto) - p.sequence++ + if conn.sendHBPacket < conn.hbPacket { - p.sendHBPacket++ + b := make([]byte, 4) + binary.BigEndian.PutUint32(b[:4], rand.Uint32()) + sendICMP(p.id, p.sequence, *p.conn, p.ipaddrServer, p.targetAddr, conn.id, (uint32)(HB), b, p.sproto, p.rproto) + p.sequence++ + conn.sendHBPacket++ + + } + } + } +} + +func (p *Client) calcHB() { + + if p.hb > 0 { + for _, conn := range p.localIdToConnMap { + + conn.avgRecvPacket = (conn.recvPacket + conn.avgRecvPacket*conn.avgRecvNum) / conn.avgRecvNum + conn.avgRecvNum++ + if conn.avgRecvNum > 10 { + conn.avgRecvNum = 0 + } + conn.recvPacket = 0 + + conn.hbPacket = conn.avgRecvPacket * 2 / 3 + + if conn.hbPacket > 0 { + fmt.Printf("calcHB %s %s %d %d\n", conn.id, conn.ipaddr.String(), conn.hbPacket, conn.sendHBPacket) + } + + conn.sendHBPacket = 0 } } } diff --git a/cmd/main.go b/cmd/main.go index 25ca475..e9f6124 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -37,7 +37,7 @@ Usage: -rproto 客户端接收ping协议的协议,默认是0 The protocol that the client receives the ping. The default is 0. - -hb 客户端保持每秒发到服务器的心跳包,用于在某些网络下更新服务器的id和seq,以接收到服务器的reply + -hb 客户端自动保持每秒发到服务器的心跳包,用于在某些网络下更新服务器的id和seq,以接收到服务器的reply,默认0关闭 ` func main() { diff --git a/pingtunnel.go b/pingtunnel.go index 646d46b..9a0ba30 100644 --- a/pingtunnel.go +++ b/pingtunnel.go @@ -22,7 +22,6 @@ const ( END uint32 = 0xAAAABBBB ) -// An Echo represents an ICMP echo request or reply message body. type MyMsg struct { TYPE uint32 ID string