目录

TCP服务器监听状态检测原理与实现技术CC代码实现

TCP服务器监听状态检测原理与实现技术(C/C++代码实现)

在网络安全和系统管理中,检测TCP服务器是否正在监听特定端口是一项常见任务。本文将介绍一个基于C语言实现的TCP服务器监听检测工具的原理、相关技术和实现细节。

概述

该工具通过发送TCP连接请求来检测目标服务器是否在指定端口上监听。它支持IPv4和IPv6,并允许用户自定义连接超时和等待超时时间。工具的核心功能包括:

  • 检测TCP服务器是否监听特定端口。
  • 支持非阻塞连接和超时机制。
  • 提供灵活的命令行选项配置。

技术原理

1. TCP三次握手

TCP连接的建立基于三次握手过程:

  1. 客户端发送 SYN 包到服务器。
  2. 服务器响应 SYN-ACK 包。
  3. 客户端发送 ACK 包完成握手。

如果服务器正在监听目标端口,它会响应 SYN-ACK 包;否则,连接将失败或超时。

2. 非阻塞连接

非阻塞套接字允许程序在发起连接后立即返回,而无需等待连接完成。这使得程序可以在连接过程中执行其他任务,提高效率。

3. poll 机制

poll 系统调用用于监控文件描述符的状态(如是否可读、可写或出错)。在本工具中, poll 用于检测套接字是否准备好进行数据传输或是否存在错误。

TCP服务器监听状态检测原理与实现技术(C/C++代码实现)

int scanfix(char *s, uint64_t *result, int scale)
{
...
	while (*s) {
		if ((unsigned)(*s)-'0' < 10) {
			if (r <= UINT64_MAX/10 && 10*r <= UINT64_MAX-((*s)-'0'))
				r = r*10 + ((*s)-'0');
			else
				return -ERANGE;
		} else if (*s == '.') {
			if (d)
				return -EINVAL;
			d = s + 1;
		} else {
			return -EINVAL;
		}

		s++;
	}

	if (!d)
		d = s;

	int o = scale - (int)(s-d);
	for (; o > 0; o--) {
		if (r > UINT64_MAX/10)
			return -ERANGE;
		r *= 10;
	}
	for (; o < 0; o++) {
		if (r % 10 != 0)
			return -ERANGE;
		r /= 10;
	}

	*result = r;

	return 0;
}

int
syn_scan(struct addrinfo *addr)
{
	int sock = socket(addr->ai_family,
	    addr->ai_socktype | SOCK_NONBLOCK,
	    addr->ai_protocol);
	struct linger l = {1, 0};
	setsockopt(sock, SOL_SOCKET, SO_LINGER, (void *)&l, sizeof (struct linger));
	int zero = 0;
	setsockopt(sock, IPPROTO_TCP, TCP_QUICKACK, (void *)&zero, sizeof zero);
	int r;
	errno = 0;
	r = connect(sock, addr->ai_addr, addr->ai_addrlen);
	if (r > 0 || errno != EINPROGRESS) {
		fprintf(stderr, "connect failed: %m\n");
		close(sock);
		return 99;
	}

	struct pollfd fds[1];
	fds[0] = (struct pollfd){ sock, POLLIN | POLLOUT | POLLERR, 0 };
	r = poll(fds, 1, connect_timeout);
	if (r == 0) {
		printf("timeout");
		return 2;
	} else if (r != 1) {
		printf("??? poll = %d %m\n", r);
		close(sock);
		return 99;
	}

...

	return 99;		
}

int
main(int argc, char *argv[])
{
...

	while ((c = getopt(argc, argv, "+46t:w:")) != -1) {
		switch (c) {
		case '4': protocol = 4; break;
		case '6': protocol = 6; break;
                case 't':
			if ((err = scanfix(optarg, &connect_timeout, 3)) < 0) {
				fprintf(stderr, "failed to parse number '%s': %s\n",
				    optarg, strerror(-err));
				goto usage;
			}
			break;
                case 'w':
			if ((err = scanfix(optarg, &wait_timeout, 9)) < 0) {
				fprintf(stderr, "failed to parse number '%s': %s\n",
				    optarg, strerror(-err));
				goto usage;
			}
			break;
                default:
		usage:
                        fprintf(stderr,
                            "Usage: %s [-w WAIT_TIMEOUT] [-t CONNECT_TIMEOUT] [HOST] PORT\n",
                            argv[0]);
                        return 99;
                }
	}

	struct addrinfo hints = {
		.ai_socktype = SOCK_STREAM,
	}, *res;
...

	clock_gettime(CLOCK_MONOTONIC, &now);
	deadline.tv_sec = now.tv_sec;
	deadline.tv_nsec = now.tv_nsec + wait_timeout;
	if (deadline.tv_nsec >= 1000000000L) {
		deadline.tv_sec += deadline.tv_nsec / 1000000000L;
		deadline.tv_nsec = deadline.tv_nsec % 1000000000L;
	}
...

	while (now.tv_sec < deadline.tv_sec ||
	    (now.tv_sec == deadline.tv_sec && now.tv_nsec <= deadline.tv_nsec)) {
		switch (syn_scan(res)) {
		case 0:
			return 0;
		case 99:
			return 99;
		case 1:
			nanosleep(&delay, 0);   // avoid busy wait
		}

		clock_gettime(CLOCK_MONOTONIC, &now);
	}

	return 2;
}

If you need the complete source code, please add the WeChat number ( c17865354792 )

1. 命令行参数解析

工具通过 getopt 函数解析命令行参数,支持以下选项:

  • -4 :强制使用IPv4。
  • -6 :强制使用IPv6。
  • -t :设置连接超时时间(单位:毫秒)。
  • -w :设置等待超时时间(单位:纳秒)。

2. 地址解析

使用 getaddrinfo 函数将目标主机名和端口解析为套接字地址结构( struct addrinfo )。该函数支持IPv4和IPv6地址,并允许指定地址族和套接字类型。

3. 非阻塞连接

通过 socket 函数创建非阻塞套接字,并使用 connect 函数发起连接请求。如果连接成功或处于进行中状态, connect 将返回特定值。

4. 超时处理

工具使用 poll 监控套接字状态,并根据用户指定的超时时间决定是否继续等待。如果连接超时或失败,工具将输出相应信息并退出。

5. 等待机制

如果用户指定了等待超时时间( -w 选项),工具将在指定时间内反复尝试连接目标服务器。每次尝试之间会使用 nanosleep 函数引入延迟,避免频繁尝试。

应用场景

该工具适用于以下场景:

  • 网络安全扫描 :检测目标服务器的开放端口。
  • 服务监控 :检查关键服务是否正常运行。
  • 自动化测试 :验证网络服务的可用性。

总结

本文介绍了基于C语言实现的TCP服务器监听检测工具的原理和实现细节。通过非阻塞连接、 poll 机制和灵活的超时配置,该工具能够高效地检测目标服务器的监听状态。它在网络管理、安全检测和自动化测试中具有广泛的应用价值。

Welcome to follow WeChat official account【 程序猿编码