前文中已经介绍了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

golang tcp keepalive实践的更多相关文章

  1. TCP KeepAlive机制理解与实践小结

    0 前言 本文将主要通过抓包并查看报文的方式学习TCP KeepAlive机制,以此加深理解. 1 TCP KeepAlive机制简介 TCP长连接下,客户端和服务器若长时间无数据交互情况下,若一方出 ...

  2. Ubuntu14.04+RabbitMQ3.6.3+Golang的最佳实践

    目录 [TOC] 1.RabbitMQ介绍 1.1.什么是RabbitMQ?   RabbitMQ 是由 LShift 提供的一个 Advanced Message Queuing Protocol ...

  3. TCP keepalive overview

    2. TCP keepalive overview In order to understand what TCP keepalive (which we will just call keepali ...

  4. 【转载】TCP保活(TCP keepalive)

    下图是我遇到tcp keepalive的例子: 以下为转载: TCP保活的缘起 双方建立交互的连接,但是并不是一直存在数据交互,有些连接会在数据交互完毕后,主动释放连接,而有些不会,那么在长时间无数据 ...

  5. TCP keepalive under Linux

    TCP Keepalive HOWTO Prev   Next 3. Using TCP keepalive under Linux Linux has built-in support for ke ...

  6. TCP keepalive

      2. TCP keepalive overview In order to understand what TCP keepalive (which we will just call keepa ...

  7. TCP连接探测中的Keepalive和心跳包. 关键字: tcp keepalive, 心跳, 保活

    1. TCP保活的必要性 1) 很多防火墙等对于空闲socket自动关闭 2) 对于非正常断开, 服务器并不能检测到. 为了回收资源, 必须提供一种检测机制. 2. 导致TCP断连的因素 如果网络正常 ...

  8. TCP Keepalive HOWTO

    TCP Keepalive HOWTO Fabio Busatto <fabio.busatto@sikurezza.org> 2007-05-04 Revision History Re ...

  9. 【 总结 】Tcp Keepalive 和 HTTP Keepalive 详解

    TCP Keepalive Tcp keepalive的起源          双方建立交互的连接,但是并不是一直存在数据交互,有些连接会在数据交互完毕后,主动释放连接,而有些不会,那么在长时间无数据 ...

随机推荐

  1. win7-32位安装mysql-5.7.27

    下载 https://dev.mysql.com/downloads/mysql/5.7.html#downloads 参考链接 https://blog.csdn.net/qq_41307443/a ...

  2. Shell编程备份数据库

    案例: 在/usr/sbin/建立Shell文件 备份后查看目录: 然后进行crontab任务调度: #每天凌晨两点十分调度一次 * * * /usr/sbin/mysql_db.sh

  3. mysql统计表中条目个数的方法举例

    说明:以下标红且加大括号的均需要替换为实际待查询的表名或数据库名. [1].统计某张或某几张表的数据量: select count(*) from {TABLE_NAME}; #or select c ...

  4. magento购物车添加减少数量 实时更新购物车

    magento实时更新购物车商品数量 <td> <button onclick="addQtyone();" type="submit"> ...

  5. IDA Pro - 使用IDA Pro逆向C++程序

    原文地址:Reversing C++ programs with IDA pro and Hex-rays 简介 在假期期间,我花了很多时间学习和逆向用C++写的程序.这是我第一次学习C++逆向,并且 ...

  6. js 字符串格式化为时间格式

    首先介绍一下我遇到的坑,找了几个关于字符串转时间的,他们都可以就我用的时候不行. 我的原因,我的字符串是MYSQL拿出来的不是标准的时间格式,是不会转成功的. 解决思路:先将字符串转为标准时间格式的字 ...

  7. 谨慎使用mysql的replace into(转载)

    MySQL 对 SQL 有很多扩展,有些用起来很方便,但有一些被误用之后会有性能问题,还会有一些意料之外的副作用,比如 REPLACE INTO. MySQL 在数据冲突时实际上是删掉了旧记录,再写入 ...

  8. SIM800c收发短信及AT指令

    一.sim800设备安装 淘宝搜索sim800,差不多就是这么个样子 购买之后,安装手机卡,卡的缺口向外插入,会有卡住的感觉,再按一下卡会弹出 安装usb转串口驱动(CH340),设备的指示灯先是快闪 ...

  9. 【Winform-右下角弹窗】实现右下角弹窗,提示信息

    网页是否经常在电脑右下角弹窗显示消息?其实Winform也是可以实现的.下面介绍两种方法. 第一步:设计窗体 第二步:实现代码 第一种方法 引用user32 声明常量 窗体Load事件 窗体FormC ...

  10. 树莓派设定笔记(Raspberry Pi 3 B+)

    树莓派默认用户名密码 pi / raspberry 一.启用root用户 设置root用户密码 sudo passwd root 开启root账户 sudo passwd --unlock root ...