服务端配置TCP探活,超出探活时间后的行为?

news/2025/2/28 4:09:25/

server端启动

(完整源码在最后)

配置探活

	setsockopt(client_fd, IPPROTO_TCP, TCP_KEEPIDLE, &(int){5}, sizeof(int));   // 空闲60秒后探测setsockopt(client_fd, IPPROTO_TCP, TCP_KEEPINTVL, &(int){10}, sizeof(int));	 // 探测间隔10秒setsockopt(client_fd, IPPROTO_TCP, TCP_KEEPCNT, &(int){5}, sizeof(int));	 // 最多探测5次

启动服务端

$ ./net 
Waiting for client connection...

client端telnet建连

telnet 9.134.128.138 8484

连接建立,server开始发送探活包

按配置,TCP_KEEPINTVL=10秒发送一次ack,server主动发起,client收到后回复ack。


15:45:03.184535 IP host-server.8484 > client-server.51878: Flags [.], ack 5, win 510, length 0
15:45:03.184799 IP client-server.51878 > host-server.8484: Flags [.], ack 1, win 502, length 015:45:13.424537 IP host-server.8484 > client-server.51878: Flags [.], ack 5, win 510, length 0
15:45:13.424808 IP client-server.51878 > host-server.8484: Flags [.], ack 1, win 502, length 015:45:23.664530 IP host-server.8484 > client-server.51878: Flags [.], ack 5, win 510, length 0
15:45:23.664769 IP client-server.51878 > host-server.8484: Flags [.], ack 1, win 502, length 015:45:33.904536 IP host-server.8484 > client-server.51878: Flags [.], ack 5, win 510, length 0
15:45:33.904779 IP client-server.51878 > host-server.8484: Flags [.], ack 1, win 502, length 015:45:44.144532 IP host-server.8484 > client-server.51878: Flags [.], ack 5, win 510, length 0
15:45:44.144774 IP client-server.51878 > host-server.8484: Flags [.], ack 1, win 502, length 015:45:54.384517 IP host-server.8484 > client-server.51878: Flags [.], ack 5, win 510, length 0
15:45:54.384755 IP client-server.51878 > host-server.8484: Flags [.], ack 1, win 502, length 015:46:04.624540 IP host-server.8484 > client-server.51878: Flags [.], ack 5, win 510, length 0
15:46:04.624798 IP client-server.51878 > host-server.8484: Flags [.], ack 1, win 502, length 0

客户端配置主动丢掉来自server的包

service iptables start
service iptables statusiptables -L -n --line-numbersudo iptables -A OUTPUT -p tcp --sport 8484 -j DROP

五次失败的探活后,server端报错

server端本来在read上等数据,探活又内核完成,探活失败后,read返回负数错误码。

perror(“read error”);打印结果:read error: Connection timed out

		ssize_t bytes_read = read(client_fd, buffer, BUFFER_SIZE - 1);if (bytes_read > 0){buffer[bytes_read] = '\0';printf("Received: %s\n", buffer);}else if (bytes_read == 0){printf("Connection closed by client[5](@ref)\n");break;}else{perror("read error");   // <<<<< 走这里break;}

server端完整代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/tcp.h>#define BUFFER_SIZE 256int main()
{int server_fd, client_fd;struct sockaddr_in server_addr, client_addr;socklen_t client_len = sizeof(client_addr);char buffer[BUFFER_SIZE];if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0){perror("socket creation failed");exit(EXIT_FAILURE);}server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = INADDR_ANY;server_addr.sin_port = htons(8484);if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0){perror("bind failed");close(server_fd);exit(EXIT_FAILURE);}if (listen(server_fd, 5) < 0){perror("listen failed");close(server_fd);exit(EXIT_FAILURE);}printf("Waiting for client connection...\n");if ((client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_len)) < 0){perror("accept failed");close(server_fd);exit(EXIT_FAILURE);}int keepalive = 1;if (setsockopt(client_fd, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive)) < 0){perror("setsockopt(SO_KEEPALIVE) failed");close(client_fd);close(server_fd);exit(EXIT_FAILURE);}setsockopt(client_fd, IPPROTO_TCP, TCP_KEEPIDLE, &(int){5}, sizeof(int));   // 空闲60秒后探测setsockopt(client_fd, IPPROTO_TCP, TCP_KEEPINTVL, &(int){10}, sizeof(int));	 // 探测间隔10秒setsockopt(client_fd, IPPROTO_TCP, TCP_KEEPCNT, &(int){5}, sizeof(int));	 // 最多探测5次printf("Client connected from %s:%d\n",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));while (1){ssize_t bytes_read = read(client_fd, buffer, BUFFER_SIZE - 1);if (bytes_read > 0){buffer[bytes_read] = '\0';printf("Received: %s\n", buffer);}else if (bytes_read == 0){printf("Connection closed by client[5](@ref)\n");break;}else{perror("read error");break;}}close(client_fd);close(server_fd);return 0;
}

http://www.ppmy.cn/news/1575413.html

相关文章

SQL_优化

1 SQL优化 (1) 数据读取 ①分区裁剪:使用时只读取需要的分区. ②列裁剪:读取操作(select、where、join、group by、sort by等),不读取不需要的列,减少IO消耗. (2) 数据筛选 ①分区先过滤,区分度大的字段先过滤. ②不在筛选字段上使用函数和表达式. (3) 分组聚合 ①使用窗口函数…

API技术深度解析:构建高效、安全与可扩展的接口服务

在当今的数字化时代&#xff0c;应用程序接口&#xff08;API&#xff0c;Application Programming Interface&#xff09;已成为连接不同软件系统和服务的桥梁&#xff0c;是推动数字化转型的关键技术之一。无论是企业内部系统集成、第三方服务接入&#xff0c;还是面向开发者…

记录一下在k3s快速创建gitlab

废话不多说&#xff0c;直接上配置文件 需要修改的地方&#xff08;备注都有写&#xff09;&#xff1a; 1.命名空间 namespace 2. claimName 文件挂载 Deployment kind: Deployment apiVersion: apps/v1 metadata:name: gitlabnamespace: cicd # 替换为您的命名空间la…

【Linux网络编程】高效I/O--select/poll服务器

目录 多路转接之select select服务器实现 获取连接 handlerEvent select服务器代码链接 select的优缺点 多路转接之poll poll服务器实现(select服务器改写) poll的优缺点 多路转接之select select的作用 I/O的本质 等 拷贝 多路转接就是通过同时等待多个文件描述…

认知重构 | 自我分化 | 苏格拉底式提问

注&#xff1a;本文为 “认知重构 | 自我分化” 相关文章合辑。 心理学上有一个词叫&#xff1a;认知重构&#xff08;改变 “非黑即白&#xff0c;一分为二” 的思维方式&#xff09; 原创 心理师威叔 心理自救 2024 年 10 月 26 日 19:08 广东 你有没有过这样的时候&#x…

Vue2+Three.js加载并展示一个三维模型(提供Gitee源码)

目录 一、案例截图 二、安装Three.js 三、代码实现 四、Gitee源码 一、案例截图 二、安装Three.js npm install three 三、代码实现 模型资源我是放在public文件夹下面的&#xff1a; 完整代码&#xff1a; <template><div><div ref"container&qu…

【Python爬虫(67)】Python爬虫实战:探秘旅游网站数据宝藏

【Python爬虫】专栏简介:本专栏是 Python 爬虫领域的集大成之作,共 100 章节。从 Python 基础语法、爬虫入门知识讲起,深入探讨反爬虫、多线程、分布式等进阶技术。以大量实例为支撑,覆盖网页、图片、音频等各类数据爬取,还涉及数据处理与分析。无论是新手小白还是进阶开发…

Three.js 入门(辅助、位移、父子关系、缩放旋转、响应式布局)

本篇主要学习内容 : 三维坐标系与辅助坐标系物体位移与父子元素物体的缩放与物体的旋转设置响应式画布与全屏控制 点赞 关注 收藏 学会了 本文使用 Three.js 的版本&#xff1a;171 基于 Vue3vite开发调试 1.三维坐标系与辅助坐标系 1.1) 导入three和轨道控制器 // 导入…