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会因残留状态无法建立新连接,最终触发超时。
修复步骤
- 每次循环创建全新会话:将
ssh_new()及会话配置移到循环内部,确保每次测试都是独立的SSH会话。 - 及时释放资源:每次循环结束后调用
ssh_free()释放当前会话,避免内存泄漏。 - 优化错误处理:单个循环的连接/认证失败不会导致整个程序退出,保证多轮测试的完整性。
重构后的代码
#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
相关产品推荐
相关产品推荐

