• golang tcp keepalive实践


    前文中已经介绍了TCP keep alive的做了详尽说明,本文结合golang,介绍如何使用TCP keep alive。

    目前golang net包不提供TCP keep alive 空闲多长时间开始探测探测总次数直接设置。

    可以使用第三方包。

    1.下载第三方包

    git clone git@github.com:felixge/tcpkeepalive.git
    

    注意放到GOPATH目录下。

    2.例子

    2.1 server

    server端,接受client连接请求,建立连接后,设置连接的空闲多长时间开始探测探测时间间隔探测总次数

    本例中,我们设置的参数如下:

    • 空闲多长时间开始探测 keepAliveIdle: 10s
    • 探测时间间隔 keepAliveInterval: 10s
    • 探测总次数 keepAliveCount:9

    server端发送一次数据后,停住。等待10s,开始发送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")
    
    }
    
    

    2.2 client

    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))
            }
    
    }
    

    3.查看结果

    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的数据包发送情况。

    在这里插入图片描述

    4.参考

    Using TCP keepalive with Go

    github tcpkeepalive

  • 相关阅读:
    SpringBoot 之 静态资源路径、显示首页、错误页
    微擎框架的缓存机制实现源码解读
    SpringBoot 之 多环境切换
    SpringBoot 之 JSR303 数据校验
    CSS——NO.6(盒模型)
    CSS——NO.5(格式化排版)
    CSS——NO.4(继承、层叠、特殊性、重要性)
    CSS——NO.3(CSS选择器)
    CSS——NO.2(CSS样式的基本知识)
    CSS——NO.1(初识CSS)
  • 原文地址:https://www.cnblogs.com/lanyangsh/p/10928127.html
Copyright © 2020-2023  润新知