云计算百科
云计算领域专业知识百科平台

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

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

概述

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

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

技术原理

1. TCP三次握手

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

  • 客户端发送SYN包到服务器。
  • 服务器响应SYN-ACK包。
  • 客户端发送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)(sd);
    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【程序猿编码】

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » TCP服务器监听状态检测原理与实现技术(C/C++代码实现)
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!