博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
socket长连接心跳保活实现
阅读量:2493 次
发布时间:2019-05-11

本文共 2916 字,大约阅读时间需要 9 分钟。

长连接:开启一个socket连接,收发完数据后,不立刻关闭连接(不会调用close()),可以多次收发数据包。

心跳:长连接在没有数据通信时,定时发送数据包(心跳),告诉对方自己的状态,以维持连接状态;心跳包不会作为通信内容。

1. 查看linux中与keepalive相关的user-driven变量

╭─cs at css in ~ using

╰─ sudo sysctl -a | grep keepalive
[sudo] password for cs:
net.ipv4.tcp_keepalive_intvl = 75 # 连续两次探活直接的时间间隔
net.ipv4.tcp_keepalive_probes = 9 # 未确认的探测次数上限,超过后就通知系统连接中断
net.ipv4.tcp_keepalive_time = 7200 # 最后发送的数据包(简单的ACK不视为数据)与第一个keepalive探测之间的间隔;将连接标记为需要保持活动状态后,将不再使用此计数器

2. 几个用于查看心跳保活情况的命令

tcpdump -i lo -nns0 port 9999

查看环路lo的端口9999上的网络数据包信息

ss -nto src :9999

显示源地址且端口为9999的 tcp socket连接状态,主要查看keepalive的探活时间倒计时:

State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 884 0 127.0.0.1:9999 127.0.0.1:45048 timer:(keepalive,58sec,0)

3. python保活的实现

在python里,心跳检测在TCP协议层会自动维护,python只需要调用接口设置就可以了

客户端:

客户端开启心跳保活,每隔一段自动发送心跳包给服务器端

#coding=utf-8'''client端'''import socketimport timehost = 'localhost'# port = 8083port = 21568client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)client.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # 在客户端开启心跳保活client.connect((host, port))while True:    client.send('hello world\r\n'.encode())    print('send data')    time.sleep(80) # 如果想验证长时间没发数据,SOCKET连接会不会断开,则可以设置时间长一点

socket实现服务器端1:

服务器端设置为长连接,简单判断客户端的心跳保活数据帧是否可正常被服务器端检测到

#coding=utf-8'''server端'''import socketBUF_SIZE = 1024host = 'localhost'port = 21568server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server.bind((host, port))server.listen(1) # 接收的连接数client, address = server.accept() # 接收连接数为1,不需要放在循环中接收while True: # 循环收发数据包,长连接    data = client.recv(BUF_SIZE)    print(data.decode()) #python3 要使用decode    # client.close() # 连接不断开,长连接

socket实现服务器端2:

服务器端也设置心跳,每隔一段时间向客户端发送心跳数据帧

import socketserver = socket.socket()server.bind(('localhost', 9999))server.listen(5)print("server start....")while True:    client, addr = server.accept()    print('peer address: ', addr)    client.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)    client.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, 120)    client.setsockopt(socket.SOL_TCP, socket.TCP_KEEPCNT, 9)    client.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, 20)

4. 检查心跳保活数据帧

tcpdump -i lo -nns0 port 9999

04:11:52.578207 IP 127.0.0.1.9999 > 127.0.0.1.45048: Flags [.], ack 547, win 512, options [nop,nop,TS val 1868813715 ecr 1868753131], length 0

04:11:52.578259 IP 127.0.0.1.45048 > 127.0.0.1.9999: Flags [.], ack 1, win 512, options [nop,nop,TS val 1868813715 ecr 1868753132], length 0
04:12:12.067660 IP 127.0.0.1.45048 > 127.0.0.1.9999: Flags [P.], seq 547:560, ack 1, win 512, options [nop,nop,TS val 1868833204 ecr 1868753132], length 13

客户端和服务器端互相发送心跳包: 互相发送一个数据长度为0、标示位为ack的包来进行探活

ss -nto src :9999

State Recv-Q Send-Q Local Address:Port Peer Address:Port

ESTAB 1079 0 127.0.0.1:9999 127.0.0.1:45048 timer:(keepalive,3.996ms,0)

每当keepalive的计时器tcp_keepalive_intvl降为0,服务器就会发送一个心跳数据帧给客户端

5. 心跳保活的完全底层实现

自定义一个结构体(心跳包或心跳帧),与其它数据包能区分开,每当一端接受到该心跳帧,就将相关变量重置。

参考资料

转载地址:http://lwerb.baihongyu.com/

你可能感兴趣的文章
海龟交易法则01_玩风险的交易者
查看>>
CTA策略02_boll
查看>>
vnpy通过jqdatasdk初始化实时数据及历史数据下载
查看>>
设计模式19_状态
查看>>
设计模式20_观察者
查看>>
vnpy学习10_常见坑02
查看>>
用时三个月,终于把所有的Python库全部整理了!拿去别客气!
查看>>
pd.stats.ols.MovingOLS以及替代
查看>>
vnpy学习11_增加测试评估指标
查看>>
资金流入流出计算方法
查看>>
海龟交易法则07_如何衡量风险
查看>>
海龟交易法则08_风险与资金管理
查看>>
海龟交易法则09_海龟式积木
查看>>
海龟交易法则10_通用积木
查看>>
海龟交易法则14_掌控心魔
查看>>
海龟交易法则16_附原版海龟交易法则
查看>>
克罗谈投资策略01_期货交易中的墨菲法则
查看>>
克罗谈投资策略02_赢家和输家
查看>>
克罗谈投资策略03_你所期望的赌博方式
查看>>
克罗谈投资策略04_感觉与现实
查看>>