From 64926ff6beb93c842413b0550cdb47ace5cbdd30 Mon Sep 17 00:00:00 2001 From: waitspring Date: Tue, 13 Dec 2022 14:19:20 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E5=8F=96=E6=B6=88Python=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E8=BE=93=E5=87=BA=E5=B7=A5=E5=85=B7=E7=9A=84=E5=86=97=E4=BD=99?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E9=9B=86=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- my/my.py | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/my/my.py b/my/my.py index e334b83..27bd665 100755 --- a/my/my.py +++ b/my/my.py @@ -57,24 +57,15 @@ class Logger(object): @staticmethod def debug(message=str): - if os.getenv('LANG') in ('en_US.UTF-8', 'zh_CN.UTF-8'): - Logger.output.debug(message) - else: - Logger.output.debug(message.decode('GBK').encode('UTF-8')) + Logger.output.debug(message) @staticmethod def info(message=str): - if os.getenv('LANG') in ('en_US.UTF-8', 'zh_CN.UTF-8'): - Logger.output.info(message) - else: - Logger.output.info(message.decode('GBK').encode('UTF-8')) + Logger.output.info(message) @staticmethod def error(message=str): - if os.getenv('LANG') in ('en_US.UTF-8', 'zh_CN.UTF-8'): - Logger.output.error(message) - else: - Logger.output.error(message.decode('GBK').encode('UTF-8')) + Logger.output.error(message) class RaisePoint(Exception): """ From 28cbeeefda0791bb26ebe17dda686cf4db67d482 Mon Sep 17 00:00:00 2001 From: waitspring Date: Tue, 13 Dec 2022 19:59:00 +0800 Subject: [PATCH 2/7] update documents --- tcping/main.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 tcping/main.c diff --git a/tcping/main.c b/tcping/main.c new file mode 100644 index 0000000..be158ee --- /dev/null +++ b/tcping/main.c @@ -0,0 +1,73 @@ +/********************************************************************************************************************** + * * + * main.c * + * Fu Xuanming (2022-2023) * + * * + ********************************************************************************************************************** + * + * + */ + +#include +#include +#include + + +/********************************************************************************************************************** + * Function * + ********************************************************************************************************************** + */ +void usage(void) { + puts("Usage: tcping [option...] socket"); + puts(" -c, --count=TIMES 配置命令发起 TIMES 次 TCP 连接, 默认值为 -1 (保持长 TCPING)"); + puts(" -i, --interval=NUM 配置两次连接中的停顿时间为 NUM 秒钟, 默认值为 0 秒钟"); + puts(" -q, --quiet 开启静默执行模式, 命令屏蔽正常输出"); + puts(" -h, --help 列出命令的帮助信息"); + puts(" -v, --version 列出命令的版本信息"); +} + +void version(void) { + puts(""); + puts("command version: alpha 1.0.0"); + puts("created by FuXuanming (waitspring)"); + puts(""); +} + + +/********************************************************************************************************************** + * Main Part * + ********************************************************************************************************************** + */ +int main(int argc, char *argv[]) { + int opt; + int count = -1; + int interval = 0; // interval = 0 设置两次连接中的停顿时间为 0 秒钟 + int quiet = 0; // quiet = 0 关闭静默执行模式, quiet = 1 开启静默执行模式 + + while ((opt = getopt(argc, argv, "c:i:qh?v")) != -1) { + switch (opt) { + case 'c': + count = atoi(optarg); + break; + case 'i': + interval = atoi(optarg); + break; + case 'q': + quiet = 1; + break; + case 'h': + usage(); + break; + case '?': + usage(); + break; + case 'v': + version(); + break; + } + } + + return 0; +} + + From a7be3ec1ab3d78c2d682c7e13d8d9e6d9d52fce0 Mon Sep 17 00:00:00 2001 From: waitspring Date: Thu, 15 Dec 2022 19:47:37 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E5=89=94=E9=99=A4tcping=E7=9A=84=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tcping/main.c | 73 --------------------------------------------------- 1 file changed, 73 deletions(-) delete mode 100644 tcping/main.c diff --git a/tcping/main.c b/tcping/main.c deleted file mode 100644 index be158ee..0000000 --- a/tcping/main.c +++ /dev/null @@ -1,73 +0,0 @@ -/********************************************************************************************************************** - * * - * main.c * - * Fu Xuanming (2022-2023) * - * * - ********************************************************************************************************************** - * - * - */ - -#include -#include -#include - - -/********************************************************************************************************************** - * Function * - ********************************************************************************************************************** - */ -void usage(void) { - puts("Usage: tcping [option...] socket"); - puts(" -c, --count=TIMES 配置命令发起 TIMES 次 TCP 连接, 默认值为 -1 (保持长 TCPING)"); - puts(" -i, --interval=NUM 配置两次连接中的停顿时间为 NUM 秒钟, 默认值为 0 秒钟"); - puts(" -q, --quiet 开启静默执行模式, 命令屏蔽正常输出"); - puts(" -h, --help 列出命令的帮助信息"); - puts(" -v, --version 列出命令的版本信息"); -} - -void version(void) { - puts(""); - puts("command version: alpha 1.0.0"); - puts("created by FuXuanming (waitspring)"); - puts(""); -} - - -/********************************************************************************************************************** - * Main Part * - ********************************************************************************************************************** - */ -int main(int argc, char *argv[]) { - int opt; - int count = -1; - int interval = 0; // interval = 0 设置两次连接中的停顿时间为 0 秒钟 - int quiet = 0; // quiet = 0 关闭静默执行模式, quiet = 1 开启静默执行模式 - - while ((opt = getopt(argc, argv, "c:i:qh?v")) != -1) { - switch (opt) { - case 'c': - count = atoi(optarg); - break; - case 'i': - interval = atoi(optarg); - break; - case 'q': - quiet = 1; - break; - case 'h': - usage(); - break; - case '?': - usage(); - break; - case 'v': - version(); - break; - } - } - - return 0; -} - - From 1fa155b9d62d97463901ef9c23022c87196fdb18 Mon Sep 17 00:00:00 2001 From: waitspring Date: Wed, 28 Dec 2022 17:17:17 +0800 Subject: [PATCH 4/7] init tcping --- tcping/tcping.c | 195 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 tcping/tcping.c diff --git a/tcping/tcping.c b/tcping/tcping.c new file mode 100644 index 0000000..c45181e --- /dev/null +++ b/tcping/tcping.c @@ -0,0 +1,195 @@ +/********************************************************************************************************************** + * * + * main.c * + * Fu Xuanming (2022-2023) * + * * + ********************************************************************************************************************** + * + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +/********************************************************************************************************************** + * Function * + ********************************************************************************************************************** + */ +void usage(void) { + puts("Usage: tcping [option...] socket"); + puts(" -c, --count=TIMES 配置命令发起 TIMES 次 TCP 连接, 默认值为 -1 (保持长 TCPING)"); + puts(" -i, --interval=NUM 配置两次连接中的停顿时间为 NUM 秒钟, 默认值为 0 秒钟"); + puts(" -q, --quiet 开启静默执行模式, 命令屏蔽正常输出"); + puts(" -h, --help 列出命令的帮助信息"); + puts(" -v, --version 列出命令的版本信息"); + puts("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); + puts("Examp: tcping -c 1 127.0.0.1:22"); + puts(" tcping -c 1 [::1]:22"); +} + +void version(void) { + puts(""); + puts("command version: alpha 1.0.0"); + puts("created by FuXuanming (waitspring)"); + puts(""); +} + +void info(const char *func, const char *info) { + char timestamp[64]; + time_t timepoint = time(NULL); + struct tm *timeinfo = localtime(&timepoint); + struct timeval tv; // 使用 sys/time.h/timeval 数据结构获取毫秒级时间戳 + + gettimeofday(&tv, NULL); + strftime(timestamp, sizeof timestamp, "%F %T", timeinfo); + fprintf(stdout, "%s.%03d INFO [%s] %s\n", timestamp, tv.tv_usec/1000, func, info); +} + +void warn(const char *func, const char *warn) { + char timestamp[64]; + time_t timepoint = time(NULL); + struct tm *timewarn = localtime(&timepoint); + struct timeval tv; + + gettimeofday(&tv, NULL); + strftime(timestamp, sizeof timestamp, "%F %T", timewarn); + fprintf(stdout, "%s.%03d WARN [%s] %s\n", timestamp, tv.tv_usec/1000, func, warn); +} + +void error(const char *func, const char *error) { + char timestamp[64]; + time_t timepoint = time(NULL); + struct tm *timerror = localtime(&timepoint); + struct timeval tv; + + gettimeofday(&tv, NULL); + strftime(timestamp, sizeof timestamp, "%F %T", timerror); + fprintf(stderr, "%s.%03d ERROR [%s] %s\n", timestamp, tv.tv_usec/1000, func, error); +} + + + +/********************************************************************************************************************** + * Function * + ********************************************************************************************************************** + */ +int judge_ip(char *ip) { + /* todo: 分切套接字得到 IPv4/IPv6 地址 + * todo: 验证 IPv4/IPv6 地址是否符合书写规范 + */ + struct in_addr ipv4; + struct in6_addr ipv6; + const char tag = ':'; + const char sign[2] = {'[', ']'}; + + ip[strlen(ip) - strlen(strrchr(ip, tag))] = '\0'; + if (strrchr(ip, sign[0])) { + ip = &strrchr(ip, sign[0])[1]; + } + if (strrchr(ip, sign[1])) { + ip[strlen(ip) - strlen(strrchr(ip, sign[1]))] = '\0'; + } + if (inet_pton(AF_INET, (char *)ip, &ipv4)) { + return 1; + } + if (inet_pton(AF_INET6, (char *)ip, &ipv6)) { + return 1; + } + + error("judge_ip", "目标地址检查失败, 目标地址不符合 IPv4/ IPv6 的书写规范"); + return 0; +} + +int judge_po(char *po) { + const char tag = ':'; + + po = &strrchr(po, tag)[1]; + for (int i = 0; i < strlen(po); i++) { + if (po[i] >= '0' && po[i] <='9') { + continue; + } else { + error("judge_po", "目标端口检查失败, 目标端口不符合书写规范"); + return 0; + } + } + if (atoi(po) > 65535) { + error("judge_po", "目标端口检查失败, 目标端口已超过取值范围"); + return 0; + } + + return 1; +} + + + +/********************************************************************************************************************** + * Main Part * + ********************************************************************************************************************** + */ +int main(int argc, char *argv[]) { + int opt; + int count = 999999; + int interval = 0; // interval = 0 设置两次连接中的停顿时间为 0 秒钟 + int quiet = 0; // quiet = 0 关闭静默执行模式, quiet = 1 开启静默执行模式 + + char *parameter; + char ip[256]; + char po[256]; + + struct sockaddr_in addr_info; + + while ((opt = getopt(argc, argv, "c:i:qhv")) != -1) { + switch (opt) { + case 'c': + count = atoi(optarg); + break; + case 'i': + interval = atoi(optarg); + break; + case 'q': + quiet = 1; + break; + case 'h': + usage(); + return 0; + case 'v': + version(); + return 0; + case '?': // getopt 函数提供给用户捕获无效的命令选项 + error("main", "选项类型检查失败, 请使用 $ tcping -h 查阅命令的帮助信息"); + return 1; + } + } + + if ((argc - optind) != 1) { + error("main", "参数数量检查失败, 请使用 $ tcping -h 查阅命令的帮助信息"); + return 1; + } else { + parameter = argv[optind]; + strcpy(ip, parameter); + strcpy(po, parameter); + } + + if (judge_ip(ip) == 0 || judge_po(po) == 0) { + error("main", "参数赋值检查失败, 请使用 $ tcping -h 查阅命令的帮助信息"); + return 1; + } + + for (int i = 0; i < count; i++) { + double ms; + struct timeval tv; + } + + return 0; +} + + From 112b2e910c0edb207055567dd3cf1e389aa93016 Mon Sep 17 00:00:00 2001 From: waitspring Date: Thu, 29 Dec 2022 15:41:20 +0800 Subject: [PATCH 5/7] update c --- tcping/tcping.c | 144 +++++++++++++++++++-- tcping/tmp.c | 333 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 464 insertions(+), 13 deletions(-) create mode 100644 tcping/tmp.c diff --git a/tcping/tcping.c b/tcping/tcping.c index c45181e..17932af 100644 --- a/tcping/tcping.c +++ b/tcping/tcping.c @@ -9,10 +9,12 @@ */ #include +#include #include #include #include #include +#include #include #include #include @@ -27,7 +29,7 @@ void usage(void) { puts("Usage: tcping [option...] socket"); puts(" -c, --count=TIMES 配置命令发起 TIMES 次 TCP 连接, 默认值为 -1 (保持长 TCPING)"); - puts(" -i, --interval=NUM 配置两次连接中的停顿时间为 NUM 秒钟, 默认值为 0 秒钟"); + puts(" -i, --interval=NUM 配置两次连接中的停顿时间为 NUM 秒钟, 默认值为 1 秒钟"); puts(" -q, --quiet 开启静默执行模式, 命令屏蔽正常输出"); puts(" -h, --help 列出命令的帮助信息"); puts(" -v, --version 列出命令的版本信息"); @@ -82,9 +84,11 @@ void error(const char *func, const char *error) { * Function * ********************************************************************************************************************** */ -int judge_ip(char *ip) { - /* todo: 分切套接字得到 IPv4/IPv6 地址 - * todo: 验证 IPv4/IPv6 地址是否符合书写规范 +int judge_ip(char *ip, char **ipp, struct sockaddr_in *addr) { + /* todo: 分切套接字得到 IPv4/IPv6 地址, 验证 IPv4/IPv6 地址是否符合书写规范 + * todo: 已经验证通过的 IPv4/IPv6 地址, 赋予 sockaddr_in.sin_addr.s_addr 数据字段 + * todo: 已经验证通过的 IPv4/IPv6 地址, 赋予 ipp 字符串指针 + * return: IPv4/IPv6 地址校验成功返回值为 1, IPv4/IPv6 地址校验失败返回值为 0 */ struct in_addr ipv4; struct in6_addr ipv6; @@ -99,9 +103,15 @@ int judge_ip(char *ip) { ip[strlen(ip) - strlen(strrchr(ip, sign[1]))] = '\0'; } if (inet_pton(AF_INET, (char *)ip, &ipv4)) { + addr->sin_family = AF_INET; + addr->sin_addr.s_addr = inet_addr(ip); + *ipp = ip; return 1; } if (inet_pton(AF_INET6, (char *)ip, &ipv6)) { + addr->sin_family = AF_INET6; + addr->sin_addr.s_addr = inet_addr(ip); + *ipp = ip; return 1; } @@ -109,7 +119,12 @@ int judge_ip(char *ip) { return 0; } -int judge_po(char *po) { +int judge_po(char *po, char **pop, struct sockaddr_in *addr) { + /* todo: 分切套接字得到端口号, 验证端口号是否符合书写规范 + * todo: 已经验证通过的端口号, 赋予 sockaddr_in.sin_port 数据字段 + * todo: 已经验证通过的端口号, 赋予 pop 字符串指针 + * return: 端口号校验成功返回值为 1, 端口号校验失败返回值为 0 + */ const char tag = ':'; po = &strrchr(po, tag)[1]; @@ -126,9 +141,69 @@ int judge_po(char *po) { return 0; } + addr->sin_port = htons(atoi(po)); + *pop = po; return 1; } +int connect_to(struct timeval *begin, struct timeval *end, struct sockaddr_in *addr) { + /* todo: 创建套接字, 并发起 TCP 连接 + * todo: 针对上述过程计时, 返回计时结果, 若连接失败则计时结果为 0 + */ + int sock; + int connect_result; + int ms; + int timeout = 10; + + gettimeofday(begin, NULL); + sock = socket(addr->sin_family, SOCK_STREAM, 0); + setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(int)); + setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(int)); + connect_result = connect(sock, (struct sockaddr *)&addr, sizeof(addr)); + close(sock); + gettimeofday(end, NULL); + ms = (1000000 * (end->tv_sec - begin->tv_sec) + (end->tv_usec - begin->tv_usec)) / 1000; + if (connect_result == 0) { + return ms; + } else { + return 0; + } +} + +int max(int *num, int size) { + int max = num[0]; + + for (int i = 0; i < size; i++) { + if (max < num[i] && num[i] != 0) { + max = num[i]; + } + } + + return max; +} + +int min(int *num, int size) { + int min = num[0]; + + for (int i = 0; i < size; i++) { + if (min > num[i] && num[i] != 0) { + min = num[i]; + } + } + + return min; +} + +int avg(int *num, int size) { + int total = 0; + + for (int i = 0; i < size; i++) { + total += num[i]; + } + + return total / size; +} + /********************************************************************************************************************** @@ -137,15 +212,18 @@ int judge_po(char *po) { */ int main(int argc, char *argv[]) { int opt; - int count = 999999; - int interval = 0; // interval = 0 设置两次连接中的停顿时间为 0 秒钟 + int count = 86400; // count = 86400 设置连接次数, 默认为 86400 次连接 (24小时不间断) + int interval = 1; // interval = 1 设置两次连接中的停顿时间为 1 秒钟 int quiet = 0; // quiet = 0 关闭静默执行模式, quiet = 1 开启静默执行模式 char *parameter; - char ip[256]; - char po[256]; + char ip[256]; + char po[256]; + char *ipp; // 指向清洗过的 IPv4/IPv6 地址 + char *pop; // 指向清洗过的端口号 - struct sockaddr_in addr_info; + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); // 使用数值 0 填充数据结构 sockaddr_in 的每个字节 while ((opt = getopt(argc, argv, "c:i:qhv")) != -1) { switch (opt) { @@ -179,16 +257,56 @@ int main(int argc, char *argv[]) { strcpy(po, parameter); } - if (judge_ip(ip) == 0 || judge_po(po) == 0) { + if (judge_ip(ip, &ipp, &addr) == 0 || judge_po(po, &pop, &addr) == 0) { + /* judge_ip() 执行结束时, 字符数组变量 ip 仍然存储完整的目标套接字 (:port 部分被切割) + * judge_po() 执行结束时, 字符数组变量 po 仍然存储完整的目标套接字 + */ error("main", "参数赋值检查失败, 请使用 $ tcping -h 查阅命令的帮助信息"); return 1; } + int ms[count]; + int max_ms = 0; + int min_ms = 0; + int avg_ms = 0; + int counts = 0; // 统计成功次数 + int counte = 0; // 统计失败次数 + for (int i = 0; i < count; i++) { - double ms; - struct timeval tv; + struct timeval begin; + struct timeval end; + + ms[i] = connect_to(&begin, &end, &addr); + if (ms[i] == 0) { + counte++; + if (quiet == 0) { + printf("Ping tcp://%s:%s - error\n", ipp, pop); + } + } else { + counts++; + if (quiet == 0) { + printf("Ping tcp://%s:%s - success: timepay %d(ms)\n", ipp, pop, ms[i]); + } + } + sleep(interval); + } + + max_ms = max(ms, count); + min_ms = min(ms, count); + avg_ms = avg(ms, count); + if (quiet == 0) { + printf("Tcping statistics tcp://%s:%s\n", ipp, pop); + printf(" %d times request success, %d times request error\n", counts, counte); + printf("Approximate trip times:\n"); + printf(" Maximum = %d(ms), Minimum = %d(ms), Average = %d(ms)\n", max_ms, min_ms, avg_ms); } + if (counte == count) { + return 2; + } + if (counte != 0) { + return 1; + } return 0; } diff --git a/tcping/tmp.c b/tcping/tmp.c new file mode 100644 index 0000000..0cec48f --- /dev/null +++ b/tcping/tmp.c @@ -0,0 +1,333 @@ +/********************************************************************************************************************** + * * + * main.c * + * Fu Xuanming (2022-2023) * + * * + ********************************************************************************************************************** + * + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +/********************************************************************************************************************** + * Function * + ********************************************************************************************************************** + */ +void usage(void) { + puts("Usage: tcping [option...] socket"); + puts(" -c, --count=TIMES 配置命令发起 TIMES 次 TCP 连接, 默认值为 -1 (保持长 TCPING)"); + puts(" -i, --interval=NUM 配置两次连接中的停顿时间为 NUM 秒钟, 默认值为 1 秒钟"); + puts(" -q, --quiet 开启静默执行模式, 命令屏蔽正常输出"); + puts(" -h, --help 列出命令的帮助信息"); + puts(" -v, --version 列出命令的版本信息"); + puts("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); + puts("Examp: tcping -c 1 127.0.0.1:22"); + puts(" tcping -c 1 [::1]:22"); +} + +void version(void) { + puts(""); + puts("command version: alpha 1.0.0"); + puts("created by FuXuanming (waitspring)"); + puts(""); +} + +void info(const char *func, const char *info) { + char timestamp[64]; + time_t timepoint = time(NULL); + struct tm *timeinfo = localtime(&timepoint); + struct timeval tv; // 使用 sys/time.h/timeval 数据结构获取毫秒级时间戳 + + gettimeofday(&tv, NULL); + strftime(timestamp, sizeof timestamp, "%F %T", timeinfo); + fprintf(stdout, "%s.%03d INFO [%s] %s\n", timestamp, tv.tv_usec/1000, func, info); +} + +void warn(const char *func, const char *warn) { + char timestamp[64]; + time_t timepoint = time(NULL); + struct tm *timewarn = localtime(&timepoint); + struct timeval tv; + + gettimeofday(&tv, NULL); + strftime(timestamp, sizeof timestamp, "%F %T", timewarn); + fprintf(stdout, "%s.%03d WARN [%s] %s\n", timestamp, tv.tv_usec/1000, func, warn); +} + +void error(const char *func, const char *error) { + char timestamp[64]; + time_t timepoint = time(NULL); + struct tm *timerror = localtime(&timepoint); + struct timeval tv; + + gettimeofday(&tv, NULL); + strftime(timestamp, sizeof timestamp, "%F %T", timerror); + fprintf(stderr, "%s.%03d ERROR [%s] %s\n", timestamp, tv.tv_usec/1000, func, error); +} + + + +/********************************************************************************************************************** + * Function * + ********************************************************************************************************************** + */ +int judge_ip(char *ip, char **ipp, struct sockaddr_in *addr) { + /* todo: 分切套接字得到 IPv4/IPv6 地址, 验证 IPv4/IPv6 地址是否符合书写规范 + * todo: 已经验证通过的 IPv4/IPv6 地址, 赋予 sockaddr_in.sin_addr.s_addr 数据字段 + * todo: 已经验证通过的 IPv4/IPv6 地址, 赋予 ipp 字符串指针 + * return: IPv4/IPv6 地址校验成功返回值为 1, IPv4/IPv6 地址校验失败返回值为 0 + */ + struct in_addr ipv4; + struct in6_addr ipv6; + const char tag = ':'; + const char sign[2] = {'[', ']'}; + + ip[strlen(ip) - strlen(strrchr(ip, tag))] = '\0'; + if (strrchr(ip, sign[0])) { + ip = &strrchr(ip, sign[0])[1]; + } + if (strrchr(ip, sign[1])) { + ip[strlen(ip) - strlen(strrchr(ip, sign[1]))] = '\0'; + } + if (inet_pton(AF_INET, (char *)ip, &ipv4)) { + addr->sin_family = AF_INET; + addr->sin_addr.s_addr = inet_addr(ip); + *ipp = ip; + return 1; + } + if (inet_pton(AF_INET6, (char *)ip, &ipv6)) { + addr->sin_family = AF_INET6; + addr->sin_addr.s_addr = inet_addr(ip); + *ipp = ip; + return 1; + } + + error("judge_ip", "目标地址检查失败, 目标地址不符合 IPv4/ IPv6 的书写规范"); + return 0; +} + +int judge_po(char *po, char **pop, struct sockaddr_in *addr) { + /* todo: 分切套接字得到端口号, 验证端口号是否符合书写规范 + * todo: 已经验证通过的端口号, 赋予 sockaddr_in.sin_port 数据字段 + * todo: 已经验证通过的端口号, 赋予 pop 字符串指针 + * return: 端口号校验成功返回值为 1, 端口号校验失败返回值为 0 + */ + const char tag = ':'; + + po = &strrchr(po, tag)[1]; + for (int i = 0; i < strlen(po); i++) { + if (po[i] >= '0' && po[i] <='9') { + continue; + } else { + error("judge_po", "目标端口检查失败, 目标端口不符合书写规范"); + return 0; + } + } + if (atoi(po) > 65535) { + error("judge_po", "目标端口检查失败, 目标端口已超过取值范围"); + return 0; + } + + addr->sin_port = htons(atoi(po)); + *pop = po; + return 1; +} + +int connect_to(struct timeval *begin, struct timeval *end, struct sockaddr_in *addr) { + /* todo: 创建套接字, 并发起 TCP 连接 + * todo: 针对上述过程计时, 返回计时结果, 若连接失败则计时结果为 0 + */ + int sock; + int connect_result; + int ms; + int timeout = 10; + int mode = 0; + // struct timeval timeout; + // fd_set sfd; + + // timeout.tv_sec = 6; + // timeout.tv_usec = 0; + + gettimeofday(begin, NULL); + sock = socket(addr->sin_family, SOCK_STREAM, 0); + setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(int)); + setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(int)); + ioctl(sock, FIONBIO, (unsigned long *)&mode); + connect_result = connect(sock, (struct sockaddr *)&addr, sizeof(addr)); + // if (connect_result == 0) { + // close(sock); + // gettimeofday(end, NULL); + // ms = (1000000 * (end->tv_sec - begin->tv_sec) + (end->tv_usec - begin->tv_usec)) / 1000; + // return ms; + // } else { + // FD_ZERO(&sfd); + // FD_SET(sock, &sfd); + // int tmp = select(sock + 1, NULL, &sfd, NULL, &timeout); + // if (tmp <= 0) { + // return 0; + // } + // } + close(sock); + gettimeofday(end, NULL); + ms = (1000000 * (end->tv_sec - begin->tv_sec) + (end->tv_usec - begin->tv_usec)) / 1000; + if (connect_result == 0) { + return ms; + } else { + return 0; + } +} + +int max(int *num, int size) { + int max = num[0]; + + for (int i = 0; i < size; i++) { + if (max < num[i] && num[i] != 0) { + max = num[i]; + } + } + + return max; +} + +int min(int *num, int size) { + int min = num[0]; + + for (int i = 0; i < size; i++) { + if (min > num[i] && num[i] != 0) { + min = num[i]; + } + } + + return min; +} + +int avg(int *num, int size) { + int total = 0; + + for (int i = 0; i < size; i++) { + total += num[i]; + } + + return total / size; +} + + + +/********************************************************************************************************************** + * Main Part * + ********************************************************************************************************************** + */ +int main(int argc, char *argv[]) { + int opt; + int count = 86400; // count = 86400 设置连接次数, 默认为 86400 次连接 (24小时不间断) + int interval = 1; // interval = 1 设置两次连接中的停顿时间为 1 秒钟 + int quiet = 0; // quiet = 0 关闭静默执行模式, quiet = 1 开启静默执行模式 + + char *parameter; + char ip[256]; + char po[256]; + char *ipp; // 指向清洗过的 IPv4/IPv6 地址 + char *pop; // 指向清洗过的端口号 + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); // 使用数值 0 填充数据结构 sockaddr_in 的每个字节 + + while ((opt = getopt(argc, argv, "c:i:qhv")) != -1) { + switch (opt) { + case 'c': + count = atoi(optarg); + break; + case 'i': + interval = atoi(optarg); + break; + case 'q': + quiet = 1; + break; + case 'h': + usage(); + return 0; + case 'v': + version(); + return 0; + case '?': // getopt 函数提供给用户捕获无效的命令选项 + error("main", "选项类型检查失败, 请使用 $ tcping -h 查阅命令的帮助信息"); + return 1; + } + } + + if ((argc - optind) != 1) { + error("main", "参数数量检查失败, 请使用 $ tcping -h 查阅命令的帮助信息"); + return 1; + } else { + parameter = argv[optind]; + strcpy(ip, parameter); + strcpy(po, parameter); + } + + if (judge_ip(ip, &ipp, &addr) == 0 || judge_po(po, &pop, &addr) == 0) { + /* judge_ip() 执行结束时, 字符数组变量 ip 仍然存储完整的目标套接字 (:port 部分被切割) + * judge_po() 执行结束时, 字符数组变量 po 仍然存储完整的目标套接字 + */ + error("main", "参数赋值检查失败, 请使用 $ tcping -h 查阅命令的帮助信息"); + return 1; + } + + int ms[count]; + int max_ms = 0; + int min_ms = 0; + int avg_ms = 0; + int counts = 0; // 统计成功次数 + int counte = 0; // 统计失败次数 + + for (int i = 0; i < count; i++) { + struct timeval begin; + struct timeval end; + + ms[i] = connect_to(&begin, &end, &addr); + if (ms[i] == 0) { + counte++; + if (quiet == 0) { + printf("Ping tcp://%s:%s - error\n", ipp, pop); + } + } else { + counts++; + if (quiet == 0) { + printf("Ping tcp://%s:%s - success: timepay %d(ms)\n", ipp, pop, ms[i]); + } + } + sleep(interval); + } + + max_ms = max(ms, count); + min_ms = min(ms, count); + avg_ms = avg(ms, count); + if (quiet == 0) { + printf("Tcping statistics tcp://%s:%s\n", ipp, pop); + printf(" %d times request success, %d times request error\n", counts, counte); + printf("Approximate trip times:\n"); + printf(" Maximum = %d(ms), Minimum = %d(ms), Average = %d(ms)\n", max_ms, min_ms, avg_ms); + } + + if (counte == count) { + return 2; + } + if (counte != 0) { + return 1; + } + return 0; +} + + From 97627206ba02ade6dd098df09e94950fa1cd1c46 Mon Sep 17 00:00:00 2001 From: waitspring Date: Thu, 29 Dec 2022 15:58:06 +0800 Subject: [PATCH 6/7] update c --- tcping/tcping.c | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/tcping/tcping.c b/tcping/tcping.c index 17932af..ce4c940 100644 --- a/tcping/tcping.c +++ b/tcping/tcping.c @@ -147,27 +147,38 @@ int judge_po(char *po, char **pop, struct sockaddr_in *addr) { } int connect_to(struct timeval *begin, struct timeval *end, struct sockaddr_in *addr) { - /* todo: 创建套接字, 并发起 TCP 连接 + /* todo: 创建套接字, 并发起 TCP 连接 (默认 10 秒钟超时) * todo: 针对上述过程计时, 返回计时结果, 若连接失败则计时结果为 0 */ int sock; int connect_result; int ms; - int timeout = 10; + int timeout_io = 10; + int mode = 1; + struct timeval timeout; + + fd_set sfd; + timeout.tv_sec = 10; + timeout.tv_usec = 0; gettimeofday(begin, NULL); sock = socket(addr->sin_family, SOCK_STREAM, 0); - setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(int)); - setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(int)); - connect_result = connect(sock, (struct sockaddr *)&addr, sizeof(addr)); + setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout_io, sizeof(int)); + setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout_io, sizeof(int)); + ioctl(sock, FIONBIO, (unsigned long *)&mode); + connect_result = connect(sock, (struct sockaddr *)addr, sizeof(*addr)); + if (connect_result != 0) { + FD_ZERO(&sfd); + FD_SET(sock, &sfd); + if (select(sock + 1, NULL, &sfd, NULL, &timeout) <= 0) { + close(sock); + return 0; + } + } close(sock); gettimeofday(end, NULL); ms = (1000000 * (end->tv_sec - begin->tv_sec) + (end->tv_usec - begin->tv_usec)) / 1000; - if (connect_result == 0) { - return ms; - } else { - return 0; - } + return ms; } int max(int *num, int size) { @@ -194,14 +205,16 @@ int min(int *num, int size) { return min; } -int avg(int *num, int size) { +int avg(int *num, int size, int counts) { int total = 0; for (int i = 0; i < size; i++) { - total += num[i]; + if (num[i] != 0) { + total += num[i]; + } } - return total / size; + return total / counts; } @@ -293,7 +306,7 @@ int main(int argc, char *argv[]) { max_ms = max(ms, count); min_ms = min(ms, count); - avg_ms = avg(ms, count); + avg_ms = avg(ms, count, counts); if (quiet == 0) { printf("Tcping statistics tcp://%s:%s\n", ipp, pop); printf(" %d times request success, %d times request error\n", counts, counte); From 4ea7a2ced256cb6d591138df02a138e31d9708f5 Mon Sep 17 00:00:00 2001 From: waitspring Date: Thu, 29 Dec 2022 17:24:57 +0800 Subject: [PATCH 7/7] update c --- tcping/tcping.c | 63 +++++---- tcping/tmp.c | 333 ------------------------------------------------ 2 files changed, 31 insertions(+), 365 deletions(-) delete mode 100644 tcping/tmp.c diff --git a/tcping/tcping.c b/tcping/tcping.c index ce4c940..f5b2dfe 100644 --- a/tcping/tcping.c +++ b/tcping/tcping.c @@ -10,11 +10,11 @@ #include #include +#include #include #include #include #include -#include #include #include #include @@ -85,10 +85,10 @@ void error(const char *func, const char *error) { ********************************************************************************************************************** */ int judge_ip(char *ip, char **ipp, struct sockaddr_in *addr) { - /* todo: 分切套接字得到 IPv4/IPv6 地址, 验证 IPv4/IPv6 地址是否符合书写规范 - * todo: 已经验证通过的 IPv4/IPv6 地址, 赋予 sockaddr_in.sin_addr.s_addr 数据字段 - * todo: 已经验证通过的 IPv4/IPv6 地址, 赋予 ipp 字符串指针 - * return: IPv4/IPv6 地址校验成功返回值为 1, IPv4/IPv6 地址校验失败返回值为 0 + /* Todo: 分切套接字得到 IPv4/IPv6 地址, 验证 IPv4/IPv6 地址是否符合书写规范 + * Todo: 已经验证通过的 IPv4/IPv6 地址, 赋予 sockaddr_in.sin_addr.s_addr 数据字段 + * Todo: 已经验证通过的 IPv4/IPv6 地址, 赋予 ipp 字符串指针 + * Return: IPv4/IPv6 地址校验成功返回值为 1, IPv4/IPv6 地址校验失败返回值为 0 */ struct in_addr ipv4; struct in6_addr ipv6; @@ -120,10 +120,10 @@ int judge_ip(char *ip, char **ipp, struct sockaddr_in *addr) { } int judge_po(char *po, char **pop, struct sockaddr_in *addr) { - /* todo: 分切套接字得到端口号, 验证端口号是否符合书写规范 - * todo: 已经验证通过的端口号, 赋予 sockaddr_in.sin_port 数据字段 - * todo: 已经验证通过的端口号, 赋予 pop 字符串指针 - * return: 端口号校验成功返回值为 1, 端口号校验失败返回值为 0 + /* Todo: 分切套接字得到端口号, 验证端口号是否符合书写规范 + * Todo: 已经验证通过的端口号, 赋予 sockaddr_in.sin_port 数据字段 + * Todo: 已经验证通过的端口号, 赋予 pop 字符串指针 + * Return: 端口号校验成功返回值为 1, 端口号校验失败返回值为 0 */ const char tag = ':'; @@ -147,38 +147,33 @@ int judge_po(char *po, char **pop, struct sockaddr_in *addr) { } int connect_to(struct timeval *begin, struct timeval *end, struct sockaddr_in *addr) { - /* todo: 创建套接字, 并发起 TCP 连接 (默认 10 秒钟超时) - * todo: 针对上述过程计时, 返回计时结果, 若连接失败则计时结果为 0 + /* Todo: 创建套接字, 并发起 TCP 连接 (默认 10 秒钟超时) + * Todo: 针对上述过程计时, 返回计时结果, 若连接失败则计时结果为 0 + * Notice: 套接字的非阻塞工作模式无法适应内网的 TCP 连接 */ int sock; int connect_result; int ms; - int timeout_io = 10; - int mode = 1; - struct timeval timeout; - - fd_set sfd; - timeout.tv_sec = 10; - timeout.tv_usec = 0; + int timeout = 10; gettimeofday(begin, NULL); sock = socket(addr->sin_family, SOCK_STREAM, 0); - setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout_io, sizeof(int)); - setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout_io, sizeof(int)); - ioctl(sock, FIONBIO, (unsigned long *)&mode); + setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(int)); + setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(int)); connect_result = connect(sock, (struct sockaddr *)addr, sizeof(*addr)); - if (connect_result != 0) { - FD_ZERO(&sfd); - FD_SET(sock, &sfd); - if (select(sock + 1, NULL, &sfd, NULL, &timeout) <= 0) { - close(sock); - return 0; - } - } close(sock); gettimeofday(end, NULL); - ms = (1000000 * (end->tv_sec - begin->tv_sec) + (end->tv_usec - begin->tv_usec)) / 1000; - return ms; + if (connect_result == 0) { + ms = (1000000 * (end->tv_sec - begin->tv_sec) + (end->tv_usec - begin->tv_usec)) / 1000; + if (ms == 0) { + /* Todo: 建立本机的 TCP 连接时, 因数据精度不够, 可能导致计时为 0 毫秒, 人工将其重置为 1 毫秒 + */ + ms = 1; + } + return ms; + } else { + return 0; + } } int max(int *num, int size) { @@ -214,7 +209,11 @@ int avg(int *num, int size, int counts) { } } - return total / counts; + if (counts != 0) { + return total / counts; + } else { + return 0; + } } diff --git a/tcping/tmp.c b/tcping/tmp.c deleted file mode 100644 index 0cec48f..0000000 --- a/tcping/tmp.c +++ /dev/null @@ -1,333 +0,0 @@ -/********************************************************************************************************************** - * * - * main.c * - * Fu Xuanming (2022-2023) * - * * - ********************************************************************************************************************** - * - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - - -/********************************************************************************************************************** - * Function * - ********************************************************************************************************************** - */ -void usage(void) { - puts("Usage: tcping [option...] socket"); - puts(" -c, --count=TIMES 配置命令发起 TIMES 次 TCP 连接, 默认值为 -1 (保持长 TCPING)"); - puts(" -i, --interval=NUM 配置两次连接中的停顿时间为 NUM 秒钟, 默认值为 1 秒钟"); - puts(" -q, --quiet 开启静默执行模式, 命令屏蔽正常输出"); - puts(" -h, --help 列出命令的帮助信息"); - puts(" -v, --version 列出命令的版本信息"); - puts("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); - puts("Examp: tcping -c 1 127.0.0.1:22"); - puts(" tcping -c 1 [::1]:22"); -} - -void version(void) { - puts(""); - puts("command version: alpha 1.0.0"); - puts("created by FuXuanming (waitspring)"); - puts(""); -} - -void info(const char *func, const char *info) { - char timestamp[64]; - time_t timepoint = time(NULL); - struct tm *timeinfo = localtime(&timepoint); - struct timeval tv; // 使用 sys/time.h/timeval 数据结构获取毫秒级时间戳 - - gettimeofday(&tv, NULL); - strftime(timestamp, sizeof timestamp, "%F %T", timeinfo); - fprintf(stdout, "%s.%03d INFO [%s] %s\n", timestamp, tv.tv_usec/1000, func, info); -} - -void warn(const char *func, const char *warn) { - char timestamp[64]; - time_t timepoint = time(NULL); - struct tm *timewarn = localtime(&timepoint); - struct timeval tv; - - gettimeofday(&tv, NULL); - strftime(timestamp, sizeof timestamp, "%F %T", timewarn); - fprintf(stdout, "%s.%03d WARN [%s] %s\n", timestamp, tv.tv_usec/1000, func, warn); -} - -void error(const char *func, const char *error) { - char timestamp[64]; - time_t timepoint = time(NULL); - struct tm *timerror = localtime(&timepoint); - struct timeval tv; - - gettimeofday(&tv, NULL); - strftime(timestamp, sizeof timestamp, "%F %T", timerror); - fprintf(stderr, "%s.%03d ERROR [%s] %s\n", timestamp, tv.tv_usec/1000, func, error); -} - - - -/********************************************************************************************************************** - * Function * - ********************************************************************************************************************** - */ -int judge_ip(char *ip, char **ipp, struct sockaddr_in *addr) { - /* todo: 分切套接字得到 IPv4/IPv6 地址, 验证 IPv4/IPv6 地址是否符合书写规范 - * todo: 已经验证通过的 IPv4/IPv6 地址, 赋予 sockaddr_in.sin_addr.s_addr 数据字段 - * todo: 已经验证通过的 IPv4/IPv6 地址, 赋予 ipp 字符串指针 - * return: IPv4/IPv6 地址校验成功返回值为 1, IPv4/IPv6 地址校验失败返回值为 0 - */ - struct in_addr ipv4; - struct in6_addr ipv6; - const char tag = ':'; - const char sign[2] = {'[', ']'}; - - ip[strlen(ip) - strlen(strrchr(ip, tag))] = '\0'; - if (strrchr(ip, sign[0])) { - ip = &strrchr(ip, sign[0])[1]; - } - if (strrchr(ip, sign[1])) { - ip[strlen(ip) - strlen(strrchr(ip, sign[1]))] = '\0'; - } - if (inet_pton(AF_INET, (char *)ip, &ipv4)) { - addr->sin_family = AF_INET; - addr->sin_addr.s_addr = inet_addr(ip); - *ipp = ip; - return 1; - } - if (inet_pton(AF_INET6, (char *)ip, &ipv6)) { - addr->sin_family = AF_INET6; - addr->sin_addr.s_addr = inet_addr(ip); - *ipp = ip; - return 1; - } - - error("judge_ip", "目标地址检查失败, 目标地址不符合 IPv4/ IPv6 的书写规范"); - return 0; -} - -int judge_po(char *po, char **pop, struct sockaddr_in *addr) { - /* todo: 分切套接字得到端口号, 验证端口号是否符合书写规范 - * todo: 已经验证通过的端口号, 赋予 sockaddr_in.sin_port 数据字段 - * todo: 已经验证通过的端口号, 赋予 pop 字符串指针 - * return: 端口号校验成功返回值为 1, 端口号校验失败返回值为 0 - */ - const char tag = ':'; - - po = &strrchr(po, tag)[1]; - for (int i = 0; i < strlen(po); i++) { - if (po[i] >= '0' && po[i] <='9') { - continue; - } else { - error("judge_po", "目标端口检查失败, 目标端口不符合书写规范"); - return 0; - } - } - if (atoi(po) > 65535) { - error("judge_po", "目标端口检查失败, 目标端口已超过取值范围"); - return 0; - } - - addr->sin_port = htons(atoi(po)); - *pop = po; - return 1; -} - -int connect_to(struct timeval *begin, struct timeval *end, struct sockaddr_in *addr) { - /* todo: 创建套接字, 并发起 TCP 连接 - * todo: 针对上述过程计时, 返回计时结果, 若连接失败则计时结果为 0 - */ - int sock; - int connect_result; - int ms; - int timeout = 10; - int mode = 0; - // struct timeval timeout; - // fd_set sfd; - - // timeout.tv_sec = 6; - // timeout.tv_usec = 0; - - gettimeofday(begin, NULL); - sock = socket(addr->sin_family, SOCK_STREAM, 0); - setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(int)); - setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(int)); - ioctl(sock, FIONBIO, (unsigned long *)&mode); - connect_result = connect(sock, (struct sockaddr *)&addr, sizeof(addr)); - // if (connect_result == 0) { - // close(sock); - // gettimeofday(end, NULL); - // ms = (1000000 * (end->tv_sec - begin->tv_sec) + (end->tv_usec - begin->tv_usec)) / 1000; - // return ms; - // } else { - // FD_ZERO(&sfd); - // FD_SET(sock, &sfd); - // int tmp = select(sock + 1, NULL, &sfd, NULL, &timeout); - // if (tmp <= 0) { - // return 0; - // } - // } - close(sock); - gettimeofday(end, NULL); - ms = (1000000 * (end->tv_sec - begin->tv_sec) + (end->tv_usec - begin->tv_usec)) / 1000; - if (connect_result == 0) { - return ms; - } else { - return 0; - } -} - -int max(int *num, int size) { - int max = num[0]; - - for (int i = 0; i < size; i++) { - if (max < num[i] && num[i] != 0) { - max = num[i]; - } - } - - return max; -} - -int min(int *num, int size) { - int min = num[0]; - - for (int i = 0; i < size; i++) { - if (min > num[i] && num[i] != 0) { - min = num[i]; - } - } - - return min; -} - -int avg(int *num, int size) { - int total = 0; - - for (int i = 0; i < size; i++) { - total += num[i]; - } - - return total / size; -} - - - -/********************************************************************************************************************** - * Main Part * - ********************************************************************************************************************** - */ -int main(int argc, char *argv[]) { - int opt; - int count = 86400; // count = 86400 设置连接次数, 默认为 86400 次连接 (24小时不间断) - int interval = 1; // interval = 1 设置两次连接中的停顿时间为 1 秒钟 - int quiet = 0; // quiet = 0 关闭静默执行模式, quiet = 1 开启静默执行模式 - - char *parameter; - char ip[256]; - char po[256]; - char *ipp; // 指向清洗过的 IPv4/IPv6 地址 - char *pop; // 指向清洗过的端口号 - - struct sockaddr_in addr; - memset(&addr, 0, sizeof(addr)); // 使用数值 0 填充数据结构 sockaddr_in 的每个字节 - - while ((opt = getopt(argc, argv, "c:i:qhv")) != -1) { - switch (opt) { - case 'c': - count = atoi(optarg); - break; - case 'i': - interval = atoi(optarg); - break; - case 'q': - quiet = 1; - break; - case 'h': - usage(); - return 0; - case 'v': - version(); - return 0; - case '?': // getopt 函数提供给用户捕获无效的命令选项 - error("main", "选项类型检查失败, 请使用 $ tcping -h 查阅命令的帮助信息"); - return 1; - } - } - - if ((argc - optind) != 1) { - error("main", "参数数量检查失败, 请使用 $ tcping -h 查阅命令的帮助信息"); - return 1; - } else { - parameter = argv[optind]; - strcpy(ip, parameter); - strcpy(po, parameter); - } - - if (judge_ip(ip, &ipp, &addr) == 0 || judge_po(po, &pop, &addr) == 0) { - /* judge_ip() 执行结束时, 字符数组变量 ip 仍然存储完整的目标套接字 (:port 部分被切割) - * judge_po() 执行结束时, 字符数组变量 po 仍然存储完整的目标套接字 - */ - error("main", "参数赋值检查失败, 请使用 $ tcping -h 查阅命令的帮助信息"); - return 1; - } - - int ms[count]; - int max_ms = 0; - int min_ms = 0; - int avg_ms = 0; - int counts = 0; // 统计成功次数 - int counte = 0; // 统计失败次数 - - for (int i = 0; i < count; i++) { - struct timeval begin; - struct timeval end; - - ms[i] = connect_to(&begin, &end, &addr); - if (ms[i] == 0) { - counte++; - if (quiet == 0) { - printf("Ping tcp://%s:%s - error\n", ipp, pop); - } - } else { - counts++; - if (quiet == 0) { - printf("Ping tcp://%s:%s - success: timepay %d(ms)\n", ipp, pop, ms[i]); - } - } - sleep(interval); - } - - max_ms = max(ms, count); - min_ms = min(ms, count); - avg_ms = avg(ms, count); - if (quiet == 0) { - printf("Tcping statistics tcp://%s:%s\n", ipp, pop); - printf(" %d times request success, %d times request error\n", counts, counte); - printf("Approximate trip times:\n"); - printf(" Maximum = %d(ms), Minimum = %d(ms), Average = %d(ms)\n", max_ms, min_ms, avg_ms); - } - - if (counte == count) { - return 2; - } - if (counte != 0) { - return 1; - } - return 0; -} - -