【问题标题】:How to perform a ping-test programmatically on Windows?如何在 Windows 上以编程方式执行 ping 测试?
【发布时间】:2020-07-14 11:58:27
【问题描述】:

我想在 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?就像后台隐藏的请求一样。

【问题讨论】:

  • 你想要this
  • 另外你想如何传达信息?
  • @Simon 我认为 OP 正在询问如何以编程方式执行 ping。
  • @RobertoCaboni 我不关注。如果他们隐藏终端,他们怎么知道结果?他们要么想将它传递给其他东西,然后隐藏终端,要么它只会运行并关闭
  • @Simon 我想他们需要了解远程对等点(在这种情况下是 Google 的 DNS)是否可以访问。

标签: c cmd request ip ping


【解决方案1】:

如果在 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中找到上述功能的描述。

【讨论】:

  • 谢谢!这正是我正在寻找的!
猜你喜欢
  • 2014-05-17
  • 2012-04-25
  • 2020-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-14
  • 2020-02-11
相关资源
最近更新 更多