首页 > 其他分享 >【go】golang tcp keepalive实践

【go】golang tcp keepalive实践

时间:2022-10-17 11:26:22浏览次数:75  
标签:err nil tcp golang Println go net conn log

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

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

可以使用第三方包。

1.下载第三方包

git clone [email protected]: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

 

标签:err,nil,tcp,golang,Println,go,net,conn,log
From: https://www.cnblogs.com/opensmarty/p/16798501.html

相关文章

  • django项目怎么利用gunicorn进行部署
    django项目怎么利用gunicorn进行部署 1、开发环境运行项目python mange.py runserver 0.0.0.0:80002、使用gunicorn在生产环境部署Gunicorn“绿色独角兽”是一个......
  • go json.Marshal 和 json.Unmarshal与结构体
    结构体属性名字小写会被忽略packagemainimport("encoding/json""fmt")typePeoplestruct{namestring`json:"name"`Heightstring`jso......
  • linux的TCP端口问题
    大运维项目安装好了,今天开始安装agent,在监控上看到所有服务器/虚机的指标数据。  出现一个问题,无论我换成什么端口,都是报错TCP连接失败 我的思路是先看下8082端口......
  • Google已将”XXX”标记为恶意扩展程序并已阻止系统安装它
    在Chrome浏览器中安装扩展程序时报错;Google已将”XXX”标记为恶意扩展程序并已阻止系统安装它 解决方法:1)将下载的扩展插件文件 *.crx,文件名crx后缀改为zip2)并用RA......
  • 云原生--argocd 自动同步
    自动同步在前面我们使用了手动同步https://www.cnblogs.com/zouzou-busy/p/16600104.html,当git仓库有变更时,需要手动点击SYNC,比较麻烦,我们也可以创建一个自动同步的应......
  • 云原生--argocd 命令行
    前戏在使用命令行的时候需要先登录#登录要指定ip和端口[root@master1~]#argocdlogin10.6.215.30:30495WARNING:servercertificatehaderror:x509:cannotv......
  • 云原生--argocd 仓库管理、集群管理
    前戏在我们之前添加应用的时候,都是在下图那里添加的,但如下图那样添加有个问题,就是我们的仓库需要认证,那是没有办法的,这时候我们就需要先将仓库设置好,在这里选择就可以了......
  • 【go】 golang 的文件写入和读取(Write()、WriteString(),bufio包:WriteString()、flush(
    1.os包1.1Write()/WriteString()方法语法打开文件funcOpenFile(namestring,flagint,permFileMode)(*File,error)写入func(f*File)WriteString(sstr......
  • 【go】golang网络通信超时设置
    网络通信中,为了防止长时间无响应的情况,经常会用到网络连接超时、读写超时的设置。本文结合例子简介golang的连接超时和读写超时设置。1.超时设置1.1连接超时funcDia......
  • go语言注释,标识符 | 17
    注释注释不会被编译,每一个包应该有相关注释。单行注释是最常见的注释形式,你可以在任何地方使用以//开头的单行注释。多行注释也叫块注释,均已以/*开头,并以*/结尾。如://......