当前位置: 首页 > news >正文

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

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 0

15: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 0

15: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 0

15: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 0

15: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 0

15: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 0

15: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 status

iptables -L -n --line-number

sudo 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 256

int 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;
}

相关文章:

  • 7.grafana的内存和CPU同时在一个表中的调整
  • 汽车悬架系统技术演进:从被动到全主动的革新之路(主动悬架类型对比)
  • 【单片机】MSP430MSP432入门
  • 大白话Vuex 核心概念(state、mutations、actions)的使用案例与原理
  • vue项目中动态添加类名样式不生效问题
  • 2025-02-26 学习记录--C/C++-C语言 整数格式说明符
  • 简单介绍JVM
  • Flutter系列教程之(6)——Tab导航与ListView使用
  • Lua的table类型的增删改查操作
  • http 协议和 https 协议的区别是什么?
  • 【1分钟学会万相文生视频】windows环境4080显卡部署Wan2.1-T2V-1.3B,亲手实操
  • 【STL】7.STL常用算法(1)
  • miqiu的分布式锁(二):实战——用JMeter验证JVM锁能否解决MySQL超卖问题
  • element-ui的组件使用
  • 每日一题——字母异位词分组
  • 2024 年出现的 11 大数据收集趋势
  • spring boot 连接FTP实现文件上传
  • linux中根目录满了
  • C#开发的Base64编码及解码完整源码及注意事项
  • 【含开题报告+文档+PPT+源码】基于大数据的交通流量预测系统
  • 做网站项目流程/广东seo网络培训
  • 重庆网站建设技术托管/如何推广公众号
  • wordpress手机号码插件/项链seo关键词
  • 东明网站建设推广/成功的网络营销案例有哪些
  • 网站建设静态代码/长春seo招聘
  • 微信微商城怎么做/搜索引擎优化的方法包括