How to perform a ping-test programmatically on Windows?

早过忘川 提交于 2020-07-22 07:52:13

问题


I'd like to make an IP-test in a C command line program on Windows .

Now I'm using the cmd-command in my program with something like this:

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;
}

Please note that the code above is just an example: with my program I will try to ping some devices, to see if they are online; if not I know there is a connection issue. Since I need only the connection status there is no need to show up the results.

Is there another way to do the same programmatically, so without cmd-window? Just like a hidden request in the background.


回答1:


If on Windows you need to check programmatically if an host is reachable, I suggest using _popen() instead of system().

In fact with pipes you can execute a command like with system(), but in addition its output is redirected to a stream. After that you can access the stream exactly how you'd do with a file, reading the output and parsing whatever you need.

At this link you can find Microsoft official documentation for _popen(). You will be easily able to find all related functions (such as _pclose()).

In the following demonstrative program a ping command is sent (asking for only two echoes to Google DNS server in order to save time). Then the obtained FILE *, opened in textual read mode, is used to access the stream with a normal loop of fread() calls:

#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;
}

Some further explanation

  • In this example only simple host reachability is verified. An host is considered reachable if at least an echo comes back. It is a starting point for any other information you might need to parse.
  • I've done it by checking the presence of TTL= substring, that I'm sure will be present in every language in case of successful ping (the output may be printed in different languages according to PC settings).
  • Tailor your buffer size to the length you expect is required to find the needed substring. In my example 1024 bytes were far enough for the expected response length.
  • You can find, commented, the print of the whole buffer. You can use that string to check everything you need (for example average ping time).
  • In order to read from the stream, feel free to use your favourite function. Another popular alternative would be fgets(), that would be great to read and parse one line at a time, and would also require a smaller reading buffer.

Similar in Linux

Though the question is about Windows, I have to say that the implementation on Linux would be very similar, based on popen(), pclose() and so on.

You can find the description of the mentioned functions in the manual page.



来源:https://stackoverflow.com/questions/60992843/how-to-perform-a-ping-test-programmatically-on-windows

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!