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的起源 双方建立交互的连接,但是并不是一直存在数据交互,有些连接会在数据交互完毕后,主动释放连接,而有些不会,那么在长时间无数据 ...
随机推荐
- dispatch事件分发
//赋值,监听change事件var el = document.getElementById('selectTimeHide');el.value=rs.text;//赋值el.dispatchEv ...
- Linux运维课程体系大纲
Linux入门: Linux系统管理: Linux服务及安全管理: httpd,lamp,lnmp Cache:memcached,varnish(缓存系统) ...
- redis 和 memache 缓存的区别
总结一: 1.数据类型 Redis数据类型丰富,支持set list等类型 memcache支持简单数据类型,需要客户端自己处理复杂对象 2.持久性 redis支持数据落地持久化存储 memcache ...
- cypress
https://community.cypress.com/docs/DOC-14090 usb3.0 only支持
- C#调用C++的dll各种传参
1. 如果函数只有传入参数,比如: //C++中的输出函数 int __declspec(dllexport) test(const int N) { ; } 对应的C#代码为: [DllImport ...
- python file对象测试数据的读写操作及OS模块介绍(四)
import from....import 引入模块 引入类 ①import 如果文件在lib下而且是python模块 :import 模块名. ②from....import from 包名.包 ...
- 用Python实现的二分查找算法(基于递归函数)
一.递归的定义 1.什么是递归:在一个函数里在调用这个函数本身 2.最大递归层数做了一个限制:997,但是也可以自己限制 1 def foo(): 2 print(n) 3 n+=1 4 foo(n) ...
- repo 回退当前分支下所有仓库到指定日期前的最新代码版本
回退命令: repo forall -c 'commitID=git log --before "2019-11-24 23:59" -1 --pretty=format:&quo ...
- 【weblogic】WTC配置(Weblogic Tuxedo Connector)
记录下工作中涉及到的WTC使用 WTC 是BEA 的WEB支持产品Weblogic和中间件产品Tuxedo之间的连接工具,全称Weblogic Tuxedo Connector.WTC使Weblogi ...
- selenium环境搭建:Error: could not find java.dll 报错问题
搭建java环境,参照其他的安装步骤,搭建即可. 问题:出现如下报错信息. Error: could not find java.dll Error: Could not find Java SE R ...