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.参考
golang tcp keepalive实践的更多相关文章
- TCP KeepAlive机制理解与实践小结
0 前言 本文将主要通过抓包并查看报文的方式学习TCP KeepAlive机制,以此加深理解. 1 TCP KeepAlive机制简介 TCP长连接下,客户端和服务器若长时间无数据交互情况下,若一方出 ...
- Ubuntu14.04+RabbitMQ3.6.3+Golang的最佳实践
目录 [TOC] 1.RabbitMQ介绍 1.1.什么是RabbitMQ? RabbitMQ 是由 LShift 提供的一个 Advanced Message Queuing Protocol ...
- TCP keepalive overview
2. TCP keepalive overview In order to understand what TCP keepalive (which we will just call keepali ...
- 【转载】TCP保活(TCP keepalive)
下图是我遇到tcp keepalive的例子: 以下为转载: TCP保活的缘起 双方建立交互的连接,但是并不是一直存在数据交互,有些连接会在数据交互完毕后,主动释放连接,而有些不会,那么在长时间无数据 ...
- TCP keepalive under Linux
TCP Keepalive HOWTO Prev Next 3. Using TCP keepalive under Linux Linux has built-in support for ke ...
- TCP keepalive
2. TCP keepalive overview In order to understand what TCP keepalive (which we will just call keepa ...
- TCP连接探测中的Keepalive和心跳包. 关键字: tcp keepalive, 心跳, 保活
1. TCP保活的必要性 1) 很多防火墙等对于空闲socket自动关闭 2) 对于非正常断开, 服务器并不能检测到. 为了回收资源, 必须提供一种检测机制. 2. 导致TCP断连的因素 如果网络正常 ...
- TCP Keepalive HOWTO
TCP Keepalive HOWTO Fabio Busatto <fabio.busatto@sikurezza.org> 2007-05-04 Revision History Re ...
- 【 总结 】Tcp Keepalive 和 HTTP Keepalive 详解
TCP Keepalive Tcp keepalive的起源 双方建立交互的连接,但是并不是一直存在数据交互,有些连接会在数据交互完毕后,主动释放连接,而有些不会,那么在长时间无数据 ...
随机推荐
- Spring Boot【快速入门】简单案例
Spring Boot[快速入门] Spring Boot 概述 Build Anything with Spring Boot:Spring Boot is the starting point ...
- CentOS7.6静默(无图形化界面)安装Oracle 11g
一.准备工作 1.准备CentOS 7 系统环境 由于是使用静默模式(silent)安装的,无需使用图形化界面,我选择了最小安装的服务器版的CentOS 7.安装完成后,只有命令行界面. 2.下载 O ...
- Linux内核链表深度分析
链表简介:链表是一种常用的数据结构,它通过指针将一系列数据节点连接成一条数据链.相对于数组,链表具有更好的动态性,建立链表时无需预先知道数据总量,可以随机分配空间,可以高效地在链表中的任意位置实时插入 ...
- jenkins插件管理提示“update information obtained:不可用ago”
jenkins插件管理遇到两个错误 (1)插件管理页面提示:There were errors checking the update sites:IOException:Unable to tunn ...
- 【bzoj 4025 改编版】graph
题意 给定一张 \(n\) 个点 \(m\) 条边的无向图,问删去每个点后,原图是不是二分图.输出一个长度为 \(n\) 的 \(\text{01}\) 串表示答案. 多组数据. \(T\le 5,\ ...
- Axure案例:用中继器实现便捷好用的3级菜单--转载
提示1:本篇教程可能不太适合新手,以及不了解中继器.全局变量.系统变量等使用的…新手 提示2:文字其实不多,截图太多,所以看上去很长,也可直接翻到末尾查看所有的用例,其实并不多 之前有介绍过使用中继器 ...
- 解决You may use special comments to disable some warnings.
问题:运行vue项目出现: You may use special comments to disable some warnings.Use // eslint-disable-next-line ...
- django admin登陆页出现TypeError at /admin/
出现此错误的原因主要是,添加多条URL时urlpatterns后面的序列符号写错了,检查所有的urls.py文件将{}改为[]. error: urlpatterns = {} right: urlp ...
- 【leetcode】1250. Check If It Is a Good Array
题目如下: Given an array nums of positive integers. Your task is to select some subset of nums, multiply ...
- Linux设置程序开机自启动,系统命令chkconfig及linux /etc/rc.d/目录的详解
整理了linux下程序开启几种方式,转载相关博客做统一记录 <linux程序设置开机自启动>转载自:https://www.cnblogs.com/flcz/p/7691532.html ...