TCP Socket链接检测方法

2023-05-16

TCP网络应用程序开发中,如果遇到了需要检查Socket链接问题,通常是对这个TCP通道的时效性提出了要求。


应用开发诉求

1)客户端需要了解管道提供正常数据通信链路

2)客户端需要确保管道异常后重新建链

3)服务端需要了解链接客户端链接状态

4)服务端需要及时释放通道异常的客户端管道资源


常用解决方法

开发应用过程中遇到这种问题,通常有以下两种方法解决:

1)通过TCP协议栈自带链路检测功能

2)通过网络应用程序心跳机制实现检测功能(这里不做展开,最简单的方式就是心跳握手)


Keepalive机制介绍

当建立一个TCP链接的时候,系统会设置一系列的定时器,其中一部分就是用来处理Keepalive过程的。当Keepalive定时器递减到0的时候,协议栈就会发送一个TCP Keepalive probe包,远端就会响应一个reply包。当发送Keepalive probe包收到reply包的时候,就可以认定链接任然是有效的。反之,就可以认为链接无效,需要进一步采取措施。当然这个机制的介入,会对TCP通信带来一定的额外开销。


典型场景

终端异常

    _____                                                     _____
   |     |                                                   |     |
   |  S  |                                                   |  C  |
   |_____|                                                   |_____|
      ^                                                         ^
      |--->--->--->-------------- SYN -------------->--->--->---|
      |---<---<---<------------ SYN/ACK ------------<---<---<---|
      |--->--->--->-------------- ACK -------------->--->--->---|
      |                                                         |
      |                                       system crash ---> X
      |
      |                                     system restart ---> ^
      |                                                         |
      |--->--->--->-------------- PSH -------------->--->--->---|
      |---<---<---<-------------- RST --------------<---<---<---|
      |                                                         |

网络异常

    _____           _____                                     _____
   |     |         |     |                                   |     |
   |  S  |         | NAT |                                   |  C  |
   |_____|         |_____|                                   |_____|
      ^               ^                                         ^
      |--->--->--->---|----------- SYN ------------->--->--->---|
      |---<---<---<---|--------- SYN/ACK -----------<---<---<---|
      |--->--->--->---|----------- ACK ------------->--->--->---|
      |               |                                         |
      |               | <--- connection deleted from table      |
      |               |                                         |
      |--->- PSH ->---| <--- invalid connection                 |
      |               |                                         |

Keepalive参数介绍

# cat /proc/sys/net/ipv4/tcp_keepalive_time
7200

# cat /proc/sys/net/ipv4/tcp_keepalive_intvl
75

# cat /proc/sys/net/ipv4/tcp_keepalive_probes
9

tcp_keepalive_time:表示2小时(7200 秒)开始发送第一个keepalive probe包
tcp_keepalive_intvl:表示每隔75秒发送一次keepalive probe包
tcp_keepalive_probes:表示如果没有收到ACK响应,连续尝试9次失败后,标记该链接断链

Keepalive参数设置

echo

# echo 600 > /proc/sys/net/ipv4/tcp_keepalive_time

# echo 60 > /proc/sys/net/ipv4/tcp_keepalive_intvl

# echo 20 > /proc/sys/net/ipv4/tcp_keepalive_probes

sysctl

# sysctl \
> net.ipv4.tcp_keepalive_time \
> net.ipv4.tcp_keepalive_intvl \
> net.ipv4.tcp_keepalive_probes
net.ipv4.tcp_keepalive_time = 7200
net.ipv4.tcp_keepalive_intvl = 75
net.ipv4.tcp_keepalive_probes = 9

# sysctl -w \
> net.ipv4.tcp_keepalive_time=600 \
> net.ipv4.tcp_keepalive_intvl=60 \
> net.ipv4.tcp_keepalive_probes=20
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 60
net.ipv4.tcp_keepalive_probes = 20

C语言编程API

int setsockopt(int s, int level, int optname,
                 const void *optval, socklen_t optlen)

TCP_KEEPCNT: overrides tcp_keepalive_probes
TCP_KEEPIDLE: overrides tcp_keepalive_time
TCP_KEEPINTVL: overrides tcp_keepalive_intvl


例如:

            /* --- begin of keepalive test program --- */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main(void);

int main()
{
   int s;
   int optval;
   socklen_t optlen = sizeof(optval);

   /* Create the socket */
   if((s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
      perror("socket()");
      exit(EXIT_FAILURE);
   }

   /* Check the status for the keepalive option */
   if(getsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen) < 0) {
      perror("getsockopt()");
      close(s);
      exit(EXIT_FAILURE);
   }
   printf("SO_KEEPALIVE is %s\n", (optval ? "ON" : "OFF"));

   /* Set the option active */
   optval = 1;
   optlen = sizeof(optval);
   if(setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) {
      perror("setsockopt()");
      close(s);
      exit(EXIT_FAILURE);
   }
   printf("SO_KEEPALIVE set on socket\n");

   /* Check the status again */
   if(getsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen) < 0) {
      perror("getsockopt()");
      close(s);
      exit(EXIT_FAILURE);
   }
   printf("SO_KEEPALIVE is %s\n", (optval ? "ON" : "OFF"));

   close(s);

   exit(EXIT_SUCCESS);
}

            /* ---  end of keepalive test program  --- */



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

TCP Socket链接检测方法 的相关文章

  • Spring 集成超时客户端

    我的 Spring 集成场景是 使用自定义协议发送数据的数十个生产者 大小和内容 我必须解码这个自定义协议 然后处理结果 所以我尝试了很多配置 目前最好的配置如下
  • 定义新的套接字选项以在 TCP 内核代码中使用

    我正在尝试向 TCP 内核代码添加一些功能 在tcp input c 我希望我实现的代码仅在某些情况下运行 我想添加一个控制标志 可以从用户空间应用程序设置它 我 认为我 需要添加一个新的套接字选项 以便我可以完成以下操作setsockop
  • 套接字编程最佳实践?

    我正在设计一个文件同步应用程序 如 DropBox 客户端在端口 443 上与服务器保持持久的安全 SSL TCP 套接字 每当在客户端上创建 更改 删除文件时 包含相关数据的数据包就会通过套接字发送到服务器 服务器对其进行处理更新服务器上
  • 用 C 处理 TCP 的部分返回

    我一直在读Beej 的网络编程指南 http beej us guide bgnet 获取 TCP 连接的句柄 在其中一个示例中 简单 TCP 流客户端的客户端代码如下所示 if numbytes recv sockfd buf MAXDA
  • 如何将我的 Kivy 客户端连接到服务器(TCP、套接字)

    因此 作为我的项目 2D 多人纸牌游戏 的一部分 我已经弄清楚如何在线托管和运行服务器脚本 我的计划是让两个单独的 kivy 客户端连接到服务器 这只是一个带有命令的脚本 但是我对操作顺序有些困惑 因为我think客户端连接可能与消息循环发
  • Boost ASIO:服务器如何知道客户端是否仍然连接?

    我在用boost asio对于服务器 客户端应用程序 服务器一次只接受一个连接 我想知道服务器验证客户端是否仍然连接的最佳方法是什么 这样做的目的是我希望能够知道客户端是否崩溃 以便我可以重新开始侦听新的连接尝试 在我的应用程序中 我使用以
  • Linux Socket write() 的错误文件描述符 错误的文件描述符 C

    我对 write 2 函数有一个有趣的问题 PrepareResponseForSetCoordinates 函数会导致写入时出现错误的文件描述符错误 这是错误行 perror 写入套接字时出错 总产量 写入套接字时出错 文件描述符错误 我
  • Nodejs TCP连接客户端端口分配

    我使用nodejs在客户端和服务器之间创建了tcp连接 网络模块 https nodejs org api net html 服务器正在侦听已经预定义的端口 并且客户端正在连接到该端口 据我了解客户端的端口是由节点动态分配的 那是对的吗 节
  • Node.js 找不到模块“tcp”

    节点在以下行崩溃 var tcp require tcp 错误文本 node js 201 throw e process nextTick error or error event on first tick Error Cannot f
  • 如何在 MAC OS X 中获得最大 TCP 接收/发送窗口?

    如何在 MAC OS X 中获得最大 TCP 接收 发送窗口 Linux中有两个ctl proc sys net core rmem max 最大 TCP 接收窗口 NET CORE RMEM MAX proc sys net core w
  • TCP 兼容性:为什么 TCP 不兼容数据包广播和组播操作?

    http en wikipedia org wiki User Datagram Protocol http en wikipedia org wiki User Datagram Protocol 与 TCP 不同 UDP 与数据包广播
  • 是否可以通过 TCP 连接到正在侦听 3G 网络端口的 iPhone?

    我正在开发一个严重依赖 P2P 的应用程序 但我目前没有任何 SIM 卡可供实验 因此我正在 wifi 网络上进行测试 我想知道 3G 网络上的 iPhone 是否可以连接以及是否需要穿越 NAT 设备 您位于提供商的路由器后面 您的 IP
  • C# - 从客户端检查 TCP/IP 套接字状态

    我想为我的 TCP IP 客户端类提供 CheckConnection 函数 以便我可以检查是否发生了错误 我自己的客户端断开连接 服务器断开连接 服务器卡住等 我有类似的东西 bool isConnectionActive false i
  • 为什么我们可以将 sockaddr 转换为 sockaddr_in

    我明白为什么强制转换很有用sockaddr to sockaddr in 但我不明白这怎么可能 据我所知 它们的大小相同sockaddr in添加了sin zero使其大小相同 我想知道编译器如何知道从哪里获取信息sockaddr in如果
  • 为什么turn服务器不支持tcp连接?

    我是 WebRTC 新手 我需要为我的 webrtc 应用程序配置我自己的 Turn 服务器 我使用以下命令安装了我的转弯服务器 apt get install coturn 我只需要通过 tcp 运行转变服务器 它不必使用 UDP 进行任
  • 自动打开命名管道和 tcp\ip

    我正在安装一个需要修改 SQL Server 的新产品 具体来说 启用 tcp ip 并打开命名管道 我知道如何手动完成 我想要的是一种通过 SQL 或 C 代码为新客户自动化执行此操作的方法 我希望有任何关于正确方向的建议 您可以使用 C
  • 简单的跨平台 TCP IP API?

    我不打算使用像 QT 或 wxWidgets 的 API 这样的大东西 我只想要可以在 Android iOS Windows Mac Linux 上运行的简单套接字 我正在制作一个事件驱动的纸牌游戏 所以 TCP 是最好的 本质上 我只想
  • 无法分配请求的地址 - 可能的原因?

    我有一个由主服务器和分布式从服务器组成的程序 从属服务器向服务器发送状态更新 如果服务器在固定时间内没有收到特定从属服务器的消息 则会将该从属服务器标记为关闭 这种情况一直在发生 通过检查日志 我发现从站只能向服务器发送一个状态更新 然后永
  • 分配 TCP/IP 端口供内部应用程序使用

    我编写了一个由 Windows 服务托管的 WCF 服务 它需要侦听已知的 TCP IP 端口 我可以在什么范围内安全地分配端口供我的组织内使用 该端口将嵌入到服务和使用该服务的客户端的配置文件中 端口 0 1023 是众所周知的端口 由
  • Linux:如何从特定端口发送TCP数据包?

    如何打开原始套接字以从特定 TCP 端口发送 我希望所有连接始终来自临时端口以下的一系列端口 如果您正在使用raw套接字 然后只需在数据包标头中填写正确的 TCP 源端口即可 相反 如果您使用 TCP 套接字接口 socket connec

随机推荐

  • VC6下采用ShellExecuteEx提升管理员权限

    bool IsOsVersionVistaOrGreater OSVERSIONINFOEX ovex CHAR szVersionInfo 1024 szVersionInfo 61 39 x00 39 设置参数的大小 xff0c 调用并
  • Redis开源代码读书笔记一(介绍)

    本人一直是C语言走过来的 xff0c 最近闲来无事 xff0c 学习和研究下Redis开源代码 xff0c 并计划随着代码的深入理解做个简单的读书笔记 xff0c 希望和大家一起学习和探讨 当然第一篇仅仅是做个介绍啦 xff0c 可能更多的
  • karate参数使用和设置debug超长延时

    常用参数 1 patch 和 put patch xff1a 只上传其中一部分参数 xff0c 不幂等put xff1a 幂等 xff0c 要上传完整参数体 2 xff0c And Param req 和 And request req P
  • Redis开源代码读书笔记二(源代码及工程结构)

    Redis是一款采用C语言开发的 lt Key Value gt 内存数据存储系统 今天主要3 0 7版本的的源代码和工程结构 xff0c 并初步分解一下Redis内部开发模块及组成 从Makefile文件和其执行过程及输出日志 xff0c
  • Redis开源代码读书笔记三(zmalloc模块)

    模块特性 61 61 支持内存分配配置 61 61 支持线程安全 61 61 支持内存分配失败异常处理流程自定义 61 61 支持字符串复制操作 61 61 支持当前内存大小占用记录 61 61 支持内存碎片化计算 61 61 支持系统内存
  • Redis开源代码读书笔记四(redis-server主程序, redis.c)

    Redis工程代码从 Redis开源代码读书笔记二 xff08 源代码及工程结构 xff09 中可以看出 xff0c 是非常出色的模块化代码 因此 xff0c 从敏捷的角度看 xff0c 是非常易于阅读和增量开发的 由于琐碎时间的原因 xf
  • Redis开源代码读书笔记五(adlist模块)

    adlist功能特性 61 61 支持双链表节点操作 ins del add create dup release search rotate index 61 61 支持双链表iter操作 get release rewind next
  • Redis开源代码读书笔记六(sds模块)

    SDS是一个动态字符串库 xff0c 主要用于字符串操作 SDS模块功能特性 61 61 支持字符串基本操作 new free dup cpy append add trim cmp range split join lower upper
  • Redis开源代码读书笔记零(Ubuntu14.04 64位安装)

    Redis代码可以在Linux OSX OpenBSD NetBSD FreeBSD系统上进行部署 xff0c 并且支持大小端CPU类型 学习环境采用了一台Ubuntu14 04 64位的系统 xff0c 所有代码的学习是基于redis 3
  • Redis开源代码读书笔记七(ae模块)

    AE模块是一个简单的文件事件和定时器事件的处理模块 AE模块功能 61 61 支持事件ms级时间粒度 61 61 支持定时器事件处理 单链表 支持删除定时器事件操作 支持事件处理流程及私有数据 61 61 支持文件事件处理 数组 支持文件读
  • Redis开源代码读书笔记八(anet模块)

    anet模块主要为对通信API的抽象和封装 anet功能特性 61 61 支持Unix Domain Socket服务 61 61 支持V4 V6版本的Tcp Socket服务 61 61 支持阻塞及非阻塞式TCP连接 61 61 支持Tc
  • Redis开源代码读书笔记九(Object模块)

    Object功能特性 61 61 支持REDIS STRING REDIS LIST REDIS SET REDIS ZSET REDIS HASH对象类型 61 61 支持对象引用计数 61 61 支持对象内存优化 61 61 支持对象比
  • 【C语言】函数默认实现和用户自定义实现编程方法 -- 【weak, strong alias】

    现在很多业务开发 xff0c 尤其是互联网应用 xff0c 绝大多数采用的是Java xff0c 这个不仅仅是Java语言的流行 xff0c 还有很多分布式框架都是采用的Java 而传统的C C 43 43 开发更为偏向底层等高效率基础功能
  • redis启动失败

    可能端口被占用 解决方法 xff08 1 xff09 打开cmd xff0c 查看端口6379是否被某个进程占用 xff0c 跳出一个空白cmd说明被占用 telnet 127 0 0 1 6379 xff08 2 xff09 重新打开一个
  • Linux下C语言实现文件遍历,支持嵌套和文件数量统计

    Linux命令行下有两个非常基本的命令 xff0c 一个是ls xff0c 一个是tree xff0c 其分别能够列出当前目录下的文件和树形方式嵌套显示目录结构 因为网络上有很多版本的文件遍历代码 xff0c 代码都没有整理过 xff0c
  • Linux系统参数配置简介

    Linux服务器在对应用程序进行优化配置的时候 xff0c 经常使用到sysctl和PAM两个模块对服务器进行优化 关于这两块的介绍也很多 xff0c 这里主要集中了相关内容 xff0c 并整体做了一个介绍 sysctl内核参数配置 使用
  • WindowsXp重启后,如何取消图标自动重排?

    问题现象 xff1a 在桌面右键 gt 排列图标 gt 自动排列 xff0c 功能取消后 xff08 对号去掉 xff09 xff0c 把图标拉到了桌面的右侧 可是注销或重启电脑之后 xff0c 图标又变成自动排列了 自动排列的对号也又自动
  • WindowsXp重启后,自定义任务栏丢失

    大致有以下几个原因导致自定义任务栏丢失 xff1a 第一 xff0c 系统设置 xff0c 重启时默认移除所有自定义任务栏 第二 xff0c 优化软件将自定义任务栏优化了 大致可以采用以下方法解决任务栏问题 xff1a 1 快速启动栏丢失
  • Linux应用程序之Helloworld入门

    对于初学者来说 xff08 本人就是 xff09 xff0c 如何开始写第一个程序至关重要 有的时候一个简单的问题会严重影响到学习的积极性和自信心 这里结合实际工作中的一些经验 xff0c 总结方法步骤 xff0c 对Linux下应用程序H
  • TCP Socket链接检测方法

    TCP网络应用程序开发中 xff0c 如果遇到了需要检查Socket链接问题 xff0c 通常是对这个TCP通道的时效性提出了要求 应用开发诉求 1 xff09 客户端需要了解管道提供正常数据通信链路 2 xff09 客户端需要确保管道异常