如何在 Windows 上以编程方式执行 ping 测试?
How to perform a ping-test programmatically on Windows?
我想在 Windows 上的 C 命令行程序中进行 IP 测试。
现在我在我的程序中使用 cmd 命令,如下所示:
if(system("ping -c1 8.8.8.8 -w 2 ") == 0){
printf("request successful\n");
return true;
}else{
printf("request not successful\n");
return false;
}
请注意,上面的代码只是一个示例:在我的程序中,我将尝试 ping 一些设备,看看它们是否在线;如果不是,我知道存在连接问题。因为我只需要连接状态,所以不需要显示结果。
是否有另一种方法可以以编程方式 执行相同的操作而不需要 cmd-window?就像后台的隐藏请求一样。
如果在 Windows 上,您需要以编程方式检查主机是否可达,我建议使用 _popen()
而不是 system()
.
事实上,使用 pipes 你可以执行类似 system()
的命令,但另外它的输出被重定向到一个流。之后,您可以完全按照处理文件的方式访问流,读取输出并解析您需要的任何内容。
在 this link 您可以找到 _popen()
的 Microsoft 官方文档。您将能够轻松找到所有相关函数(例如 _pclose()
)。
在下面的演示程序中,发送了一个 ping
命令(为了节省时间只要求向 Google DNS 服务器发送两次回显)。然后获得的 FILE *
,以文本读取模式打开,用于通过 fread()
调用的 正常 循环访问流:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define BUFFER_SIZE 1024
char buffer[BUFFER_SIZE] = { 0 };
int main( void )
{
FILE * pipe = _popen( "ping 8.8.8.8 -n 2", "rt" );
if( pipe != NULL )
{
int rd = 0, ret;
while( ( ret = fread( buffer+rd, 1, BUFFER_SIZE - rd, pipe ) ) > 0 )
{
rd += ret;
}
if( strstr( buffer, "TTL=" ) != NULL )
{
printf( "\nThe host is reachable!\n" );
}
else
{
printf( "\nThe host is NOT reachable!\n" );
}
//printf( "%d bytes read\n\n%s\n", rd, buffer );
_pclose( pipe );
}
else
{
printf( "Error in pipe opening!\n" );
}
return 0;
}
一些进一步的解释
- 在此示例中,仅验证简单主机 可达性。如果至少有回声返回,则主机被认为是可达的。它是您可能需要解析的任何其他信息的起点。
- 我通过检查
TTL=
子字符串的存在来做到这一点,我确信在成功 ping 的情况下,每种语言都会出现(输出可能会根据 PC 以不同的语言打印)设置)。
- 根据您期望的长度调整缓冲区大小,以找到所需的子字符串。在我的示例中,1024 个字节对于预期的响应长度已经足够了。
- 您可以找到、评论、打印整个缓冲区。您可以使用该字符串来检查您需要的一切(例如平均 ping 时间)。
- 要从流中读取,请随意使用您喜欢的功能。另一种流行的替代方法是
fgets()
,一次读取和解析一行非常好,并且还需要较小的读取缓冲区。
类似 Linux
虽然问题是关于 Windows,但我不得不说 Linux 上的实现非常相似,基于 popen()
、pclose()
等等.
您可以在 manual page.
中找到上述功能的说明
我想在 Windows 上的 C 命令行程序中进行 IP 测试。
现在我在我的程序中使用 cmd 命令,如下所示:
if(system("ping -c1 8.8.8.8 -w 2 ") == 0){
printf("request successful\n");
return true;
}else{
printf("request not successful\n");
return false;
}
请注意,上面的代码只是一个示例:在我的程序中,我将尝试 ping 一些设备,看看它们是否在线;如果不是,我知道存在连接问题。因为我只需要连接状态,所以不需要显示结果。
是否有另一种方法可以以编程方式 执行相同的操作而不需要 cmd-window?就像后台的隐藏请求一样。
如果在 Windows 上,您需要以编程方式检查主机是否可达,我建议使用 _popen()
而不是 system()
.
事实上,使用 pipes 你可以执行类似 system()
的命令,但另外它的输出被重定向到一个流。之后,您可以完全按照处理文件的方式访问流,读取输出并解析您需要的任何内容。
在 this link 您可以找到 _popen()
的 Microsoft 官方文档。您将能够轻松找到所有相关函数(例如 _pclose()
)。
在下面的演示程序中,发送了一个 ping
命令(为了节省时间只要求向 Google DNS 服务器发送两次回显)。然后获得的 FILE *
,以文本读取模式打开,用于通过 fread()
调用的 正常 循环访问流:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define BUFFER_SIZE 1024
char buffer[BUFFER_SIZE] = { 0 };
int main( void )
{
FILE * pipe = _popen( "ping 8.8.8.8 -n 2", "rt" );
if( pipe != NULL )
{
int rd = 0, ret;
while( ( ret = fread( buffer+rd, 1, BUFFER_SIZE - rd, pipe ) ) > 0 )
{
rd += ret;
}
if( strstr( buffer, "TTL=" ) != NULL )
{
printf( "\nThe host is reachable!\n" );
}
else
{
printf( "\nThe host is NOT reachable!\n" );
}
//printf( "%d bytes read\n\n%s\n", rd, buffer );
_pclose( pipe );
}
else
{
printf( "Error in pipe opening!\n" );
}
return 0;
}
一些进一步的解释
- 在此示例中,仅验证简单主机 可达性。如果至少有回声返回,则主机被认为是可达的。它是您可能需要解析的任何其他信息的起点。
- 我通过检查
TTL=
子字符串的存在来做到这一点,我确信在成功 ping 的情况下,每种语言都会出现(输出可能会根据 PC 以不同的语言打印)设置)。 - 根据您期望的长度调整缓冲区大小,以找到所需的子字符串。在我的示例中,1024 个字节对于预期的响应长度已经足够了。
- 您可以找到、评论、打印整个缓冲区。您可以使用该字符串来检查您需要的一切(例如平均 ping 时间)。
- 要从流中读取,请随意使用您喜欢的功能。另一种流行的替代方法是
fgets()
,一次读取和解析一行非常好,并且还需要较小的读取缓冲区。
类似 Linux
虽然问题是关于 Windows,但我不得不说 Linux 上的实现非常相似,基于 popen()
、pclose()
等等.
您可以在 manual page.
中找到上述功能的说明