代码
// netcheck.c
#define POSIX_C_SOURCE 200112L#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <ctype.h>#define COUNT 5#define THRESHOLD_LOSS 5 // percent#define THRESHOLD_RTT 1000 // msstatic void now_str(char *buf, size_t sz) { time_t t = time(NULL); struct tm tm; localtime_r(&t, &tm); strftime(buf, sz, “%Y-%m-%d %H:%M:%S”, &tm);}static void now_filename(char *buf, size_t sz) { time_t t = time(NULL); struct tm tm; localtime_r(&t, &tm); strftime(buf, sz, "%Y%m%d%H%M%S", &tm);}static void run_and_record(const char *cmd, FILE *logf) { FILE *fp = popen(cmd, “r”); if (!fp) { if (logf) fprintf(logf, “Failed to run: %s\n”, cmd); printf(“Failed to run: %s\n”, cmd); return; } char line[4096]; while (fgets(line, sizeof(line), fp)) { fputs(line, stdout); if (logf) fputs(line, logf); } pclose(fp);}static int command_exists(const char *name) { char cmd[256]; snprintf(cmd, sizeof(cmd), “command -v %s >/dev/null 2>&1”, name); return (system(cmd) == 0);}static int parse_packet_loss(const char *text) { const char *p = strstr(text, “packet loss”); if (!p) return -1; const char *pct = p; while (pct > text && *pct != ‘%’) pct–; if (pct == text) return -1; const char *start = pct - 1; while (start > text && (isdigit((unsigned char)*start) || *start==’.’)) start–; start++; int val = atoi(start); return val;}static double parse_avg_rtt(const char *text) { const char *p = strstr(text, “rtt min/avg/max”); if (!p) p = strstr(text, “round-trip min/avg/max”); if (!p) return -1.0; const char *eq = strchr(p, ‘=’); if (!eq) return -1.0; eq++; while (*eq && (*eq==’ ’ || *eq==’\t’)) eq++; double minv, avgv, maxv, mdevv; if (sscanf(eq, “%lf/%lf/%lf/%lf”, &minv, &avgv, &maxv, &mdevv) == 4) { return avgv; } return -1.0;}int main(int argc, char **argv) { if (argc < 2) { fprintf(stderr, “错误:请指定要ping的域名\n”); fprintf(stderr, “用法: %s <域名>\n”, argv[0]); return 1; } const char *domain = argv[1]; char start_time[64]; now_str(start_time, sizeof(start_time)); printf(“开始网络质量检测…\n”); printf(“目标域名: %s\n”, domain); printf(“Ping次数: %d\n”, COUNT); printf(“检测时间: %s\n”, start_time); printf("----------------------------------------\n"); char cmd_ping_quiet[512]; snprintf(cmd_ping_quiet, sizeof(cmd_ping_quiet), “LC_ALL=C ping -c %d -q %s 2>&1”, COUNT, domain); FILE *fp = popen(cmd_ping_quiet, “r”); if (!fp) { fprintf(stderr, “错误:无法执行 ping 命令\n”); return 1; } char outbuf[16384] = {0}; size_t len = 0; char line[1024]; while (fgets(line, sizeof(line), fp)) { size_t l = strlen(line); if (len + l < sizeof(outbuf) - 1) { memcpy(outbuf + len, line, l); len += l; outbuf[len] = ‘\0’; } } int status = pclose(fp); if (status != 0) { printf(“错误:无法ping通域名 %s 或 ping 命令失败\n”, domain); if (len) { printf(“ping 输出:\n%s\n”, outbuf); } return 1; } int packet_loss = parse_packet_loss(outbuf); double avg_rtt = parse_avg_rtt(outbuf); if (packet_loss < 0 || avg_rtt < 0.0) { printf(“错误:无法解析ping结果\n”); printf(“ping 原始输出:\n%s\n”, outbuf); return 1; } printf(“丢包率: %d%%\n”, packet_loss); printf(“平均RTT: %.3fms\n”, avg_rtt); int bad = 0; if (packet_loss > THRESHOLD_LOSS) bad = 1; if (avg_rtt > THRESHOLD_RTT) bad = 1; if (bad) { printf(“警告:网络质量超过阈值!\n”); printf("----------------------------------------\n"); printf(“详细网络参数记录:\n”); printf(“检测时间: %s\n”, start_time); printf(“目标域名: %s\n”, domain); char timestr[32]; now_filename(timestr, sizeof(timestr)); char log_file[512]; char domain_safe[256]; snprintf(domain_safe, sizeof(domain_safe), “%s”, domain); for (char *p = domain_safe; *p; ++p) if (*p == ‘/’ || *p == ‘\’) *p = '’; snprintf(log_file, sizeof(log_file), "network_alert%s_%s.log", domain_safe, timestr); FILE *logf = fopen(log_file, “w”); if (!logf) { printf(“无法打开日志文件写入: %s\n”, log_file); logf = NULL; } else { fprintf(logf, “网络质量告警报告\n”); fprintf(logf, “时间: %s\n”, start_time); fprintf(logf, “域名: %s\n”, domain); fprintf(logf, “丢包率: %d%% (阈值: %d%%)\n”, packet_loss, THRESHOLD_LOSS); fprintf(logf, “平均RTT: %.3fms (阈值: %dms)\n”, avg_rtt, THRESHOLD_RTT); fprintf(logf, “----------------------------------------\n”); fprintf(logf, “ping 原始输出:\n%s\n”, outbuf); } printf("=== 网络接口信息 ===\n"); if (command_exists(“ifconfig”)) { run_and_record(“ifconfig 2>/dev/null”, logf

被折叠的 条评论
为什么被折叠?



