前文中已经介绍了TCP keep alive的做了详尽说明,本文结合golang,介绍如何使用TCP keep alive。
目前golang net包不提供TCP keep alive 开始探测时间
、 探测总次数
直接设置。
使用第三方包,方便设置开始探测时间
、探测时间间隔
、探测总次数
。
git clone git@github.com:felixge/tcpkeepalive.git
server代码中client发送连接请求,建立连接后,设置连接的开始探测时间
、探测时间间隔
、探测总次数
。
server发送一次数据后,停住。接着开始发送tcp keep alive.
server 代码如下:
package main
import (
"net"
"log"
"time"
"github.com/tcpkeepalive"
)
func main() {
addr := "0.0.0.0:8080"
tcpAddr, err := net.ResolveTCPAddr("tcp",addr)
if err != nil {
log.Fatalf("net.ResovleTCPAddr fail:%s", addr)
}
listener, err := net.ListenTCP("tcp", tcpAddr)
if err != nil {
log.Fatalf("listen %s fail: %s", addr, err)
} else {
log.Println("rpc listening", addr)
}
for {
conn, err := listener.Accept()
if err != nil {
log.Println("listener.Accept error:", err)
continue
}
go handleConnection(conn)
}
}
func setTcpKeepAlive(conn net.Conn) (*tcpkeepalive.Conn, error) {
newConn, err := tcpkeepalive.EnableKeepAlive(conn)
if err != nil {
log.Println("EnableKeepAlive failed:", err)
return nil, err
}
err = newConn.SetKeepAliveIdle(10*time.Second)
if err != nil {
log.Println("SetKeepAliveIdle failed:", err)
return nil, err
}
err = newConn.SetKeepAliveCount(9)
if err != nil {
log.Println("SetKeepAliveCount failed:", err)
return nil, err
}
err = newConn.SetKeepAliveInterval(10*time.Second)
if err != nil {
log.Println("SetKeepAliveInterval failed:", err)
return nil, err
}
return newConn, nil
}
func handleConnection(conn net.Conn) {
defer conn.Close()
newConn, err := setTcpKeepAlive(conn)
if err != nil {
log.Println("setTcpKeepAlive failed:", err)
return
}
var buffer []byte = []byte("You are welcome. I'm server.")
for {
time.Sleep(1*time.Second)
n, err := newConn.Write(buffer)
if err != nil {
log.Println("Write error:", err)
break
}
log.Println("send:", n)
select{}
}
log.Println("connetion end")
}
client端很简单,负责接收数据。
package main
import (
"fmt"
"net"
"os"
)
func main() {
conn, err := net.Dial("tcp", "127.0.0.1:8080")
if err != nil {
fmt.Println("dial failed:", err)
os.Exit(1)
}
defer conn.Close()
buffer := make([]byte, 512)
for {
n, err := conn.Read(buffer)
if err != nil {
fmt.Println("Read failed:", err)
return
}
fmt.Println("count:", n, "msg:", string(buffer))
}
}
server输出
019/05/26 22:22:00 rpc listening 0.0.0.0:8080
2019/05/26 22:22:15 send: 28
client输出
count: 28 msg: You are welcome. I'm server.
通过tcpdump 或者wireshark抓包,可以看到TCP Keep-Alive的数据包发送情况。
原文:https://www.cnblogs.com/lanyangsh/p/10928127.html