tcp心跳

584 阅读1分钟

实验

准备工作:

  1. 内核参数: 观察系统是否存在以下的内核参数,由于是协议栈支持,不一定能在所有系统上实现。

  1. 本次试验采取netcat作为服务端,客户端设置套接字选项进行调用,并通过wireshark进行观察。

Step1. 启动netcat

Step2. 运行客户端代码

#!user/bin/python
# _*_ coding: utf-8 _*_
 
# @File    :   test_tcp_healthcheck.py
# @Version :   1.0
# @Author  :   
# @Email   :   
# @Time    :   2020/03/27 15:08:56
#Description:
 
import time
import unittest
import socket


class TcpHealthCheckTestCase(unittest.TestCase):

    def setUp(self):
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)

    def test_send_health(self):
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # 开启tcp keepalive
        self.sock.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, 10) # 开启空闲探测机制
        self.sock.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, 2) # 开启探测的间隔时间
        self.sock.setsockopt(socket.SOL_TCP, socket.TCP_KEEPCNT, 2) # 开启探测的次数

        self.sock.connect(("172.17.220.146", 9911))
        self.sock.send(b"1234")
        time.sleep(60)
        self.sock.close()


if __name__ == "__main__":
    unittest.main()

Step3. 启动wireshark并设置相应的条件

可以发现探测客户端会间隔一段时间进行探活

类型(心跳), 长度, 时间戳

问题:

为什么有tcp层的心跳,还需要实现应用层的心跳机制?

假设我的心跳的目的是为了维持连接的话,反正服务端上存在过大冗余的连接数,那么可以在服务端启动心跳做探测,但是这块存在两个问题。

  1. TCP协议包含keep alive,但不是所有系统设备可以支持。
  2. TCP keepalive属于tcp协议包,在连接之间有proxy或者nat,他们可能不会处理tcp keep alive。

假设我平台支持keep alive,但我想实施心跳的目的是探测服务端是否可用,是否处理不可工作状态,这个时候结合业务断开tcp连接,由客户端做异常处理。应用自实现心跳最大的好处,就是能适应复杂的网络结构。