You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SSH登录超时问题及错误密码验证延迟测试程序重构咨询

问题

我写了一段基于libssh的C程序,用来测试目标服务器设置的错误密码登录延迟(服务器已设为30秒)。但运行后发现只有第一次请求得到预期响应,后续三次请求全因Socket超时断开,耗时长达120秒。附上程序代码和运行输出,请问怎么重构程序才能准确测量获得重新输入账号密码机会的耗时?

原程序代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <libssh/libssh.h>

#define BILLION 1000000000.0

int main(void) {
    struct timespec start, finish;
    time_t t = time(NULL);

    ssh_session session;

    int rc;
    int session_status;
    session = ssh_new();

    const char *host = "127.0.0.1";
    const char *port = "22";
    const char *username = "user";
    const char *password = "pass";

    char *reply;

    ssh_options_set(session, SSH_OPTIONS_HOST, host);
    ssh_options_set(session, SSH_OPTIONS_PORT_STR, port);
    ssh_options_set(session, SSH_OPTIONS_USER, username);

    session_status = ssh_get_status(session);
    printf("Session status: %d\n", session_status);

    for (int i = 0; i < 4; ++i) {
        clock_gettime(CLOCK_REALTIME, &start);
        rc = ssh_connect(session);

        if (rc != SSH_OK) {
            fprintf(stderr, "Error connecting to %s: %s\n", host, ssh_get_error(session));
            ssh_free(session);
            exit(-1);
        }

        if (ssh_userauth_password(session, NULL, password) == SSH_AUTH_SUCCESS) {
            reply = "Authentication succeeded with incorrect password.";
        }
        else {
            reply = "Authentication failed with incorrect password.";
            fprintf(stderr, "Error authenticating with incorrect password: %s\n", ssh_get_error(session));
        }
        clock_gettime(CLOCK_REALTIME, &finish);

        double time_spent = (finish.tv_sec - start.tv_sec) + (finish.tv_nsec - start.tv_nsec) / BILLION;

        struct tm tm = *localtime(&start.tv_sec);
        printf("[%d-%02d-%02d %02d:%02d:%02d] Status:%s ",
                tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, reply);
        printf("Elapsed time: %.4f seconds.\n", time_spent);

        ssh_disconnect(session);
    }

    ssh_free(session);

    return (0);
}

原运行输出

Session status: 0
Error authenticating with incorrect password: Access denied for 'password'. Authentication that can continue: publickey,password
[2024-01-11 16:27:17] Status:Authentication failed with incorrect password. Elapsed time: 64.8060 seconds.
Error authenticating with incorrect password: Socket error: disconnected
[2024-01-11 16:28:22] Status:Authentication failed with incorrect password. Elapsed time: 120.0131 seconds.
Error authenticating with incorrect password: Socket error: disconnected
[2024-01-11 16:30:22] Status:Authentication failed with incorrect password. Elapsed time: 120.0148 seconds.
Error authenticating with incorrect password: Socket error: disconnected
[2024-01-11 16:32:22] Status:Authentication failed with incorrect password. Elapsed time: 120.0143 seconds.

解决方案

问题根源

你复用了同一个ssh_session对象,在ssh_disconnect后没有正确重置会话状态。libssh的会话对象在断开连接后无法直接复用,后续调用ssh_connect会因残留状态无法建立新连接,最终触发超时。

修复步骤

  1. 每次循环创建全新会话:将ssh_new()及会话配置移到循环内部,确保每次测试都是独立的SSH会话。
  2. 及时释放资源:每次循环结束后调用ssh_free()释放当前会话,避免内存泄漏。
  3. 优化错误处理:单个循环的连接/认证失败不会导致整个程序退出,保证多轮测试的完整性。

重构后的代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <libssh/libssh.h>

#define BILLION 1000000000.0

int main(void) {
    struct timespec start, finish;

    const char *host = "127.0.0.1";
    const char *port = "22";
    const char *username = "user";
    const char *password = "pass";

    for (int i = 0; i < 4; ++i) {
        // 每次循环创建新会话
        ssh_session session = ssh_new();
        if (session == NULL) {
            fprintf(stderr, "Failed to create SSH session\n");
            continue;
        }

        // 配置会话选项
        ssh_options_set(session, SSH_OPTIONS_HOST, host);
        ssh_options_set(session, SSH_OPTIONS_PORT_STR, port);
        ssh_options_set(session, SSH_OPTIONS_USER, username);

        clock_gettime(CLOCK_REALTIME, &start);
        int rc = ssh_connect(session);
        if (rc != SSH_OK) {
            fprintf(stderr, "Error connecting to %s: %s\n", host, ssh_get_error(session));
            ssh_free(session);
            continue;
        }

        char *reply;
        if (ssh_userauth_password(session, NULL, password) == SSH_AUTH_SUCCESS) {
            reply = "Authentication succeeded with incorrect password.";
        } else {
            reply = "Authentication failed with incorrect password.";
            fprintf(stderr, "Error authenticating with incorrect password: %s\n", ssh_get_error(session));
        }
        clock_gettime(CLOCK_REALTIME, &finish);

        // 计算并输出耗时
        double time_spent = (finish.tv_sec - start.tv_sec) + (finish.tv_nsec - start.tv_nsec) / BILLION;
        struct tm tm = *localtime(&start.tv_sec);
        printf("[%d-%02d-%02d %02d:%02d:%02d] Status:%s ",
                tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, reply);
        printf("Elapsed time: %.4f seconds.\n", time_spent);

        // 断开连接并释放会话资源
        ssh_disconnect(session);
        ssh_free(session);
    }

    return 0;
}

效果说明

重构后每次测试都会建立全新的SSH连接,避免旧会话状态干扰,能准确测量服务器错误密码的延迟时间,不会再出现Socket超时的问题。


内容的提问来源于stack exchange,提问作者AbreQueVoy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 09:58:20