微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在c中捕获ping的输出

如何通过pipe道直接捕获ping命令的输出

这是我的代码

int main () { FILE *cmd = popen ( "ping -c 3 google.com | grep icmp","r" );//ping google char *s = malloc ( sizeof ( char ) * 200 ); while ( 1 ) { fgets ( s,sizeof ( char )*200,cmd ); printf ( "%s",s);//show outcome if ( strstr ( s,"icmp_req=3" ) != 0 ) break; } pclose ( cmd ); return 0; }

程序结束后,会同时显示输出。 但是我想在程序执行时立即读取输出

标题中的EXPORT_SYMBOL导致“导出两次”错误

为什么不能将linux服务绑定到环回?

添加generics来形成

在非pipe理员帐户上使用pipe理员权限自动启动WinForms应用程序

创build父窗口的DLL插件不能正确处理消息

选项卡控件及其子窗口

C ++找出正在使用的dynamic内存

添加一个菜单项到Windows资源pipe理器右键单击上下文菜单在C#中

从pipe道或sockets上读取一端closures到EOF是否安全?

如何在Linux中删除一个文件,我只有文件描述符

<stdio.h>是认缓冲的, stdout是行缓冲的。

替换你的printf("%s",s); 用printf("%sn",s); (结尾的换行符将刷新stdout缓冲区)或添加一个调用fflush(NULL); 就在它之后。

实际上,你的问题与ping无关,但管道是缓冲的。

您可以执行较低级别的pipe , fork , dup2 , read系统调用并显式管理管道上的缓冲区。 那么调用poll可能会有用。

你可以考虑使用一个像libping这样的ICMP ping库,或者考虑使用wget程序,或者最好使用libcurl ;或许一个简单的HTTP HEAD请求就足够了。 作为一般性建议,避免使用popen或system分叉进程(因为目标计算机上可用的命令可能不相同)。

阅读一些很好的Linux编程书籍,如http://advancedlinuxprogramming.com/

这是一个代码,它使用liboping每秒钟 ping http://www.xively.com并显示延迟&#x3002; 你可以在你的Ubuntu机器上安装liboping静态/动态库文件和头文件,如下所示: sudo apt-get install liboping0 liboping-dev oping

然后用上面的库编译下面的程序( gcc -o test test.c -loping )。 并以超级用户身份运行可执行文件(sudo)。

test.c的:

/* * 1. install liboping,eg `sudo apt-get install liboping0 liboping-dev oping` * 2. Compile with -loping,eg `gcc -o test test.c -loping` * 3. Execute using sudo as super user,eg `sudo ./test` */ #include <stdlib.h> #include <stdio.h> #include <oping.h> int main(int argc,char **argv) { pingobj_t *ping; pingobj_iter_t *iter; if ((ping = ping_construct()) == NULL) { fprintf(stderr,"ping_construct Failedn"); return (-1); } printf("ping_construct() successn"); if (ping_host_add(ping,"www.xively.com") < 0) { const char * errmsg = ping_get_error(ping); fprintf(stderr,"ping_host_add(www.xively.com) Failed. %sn",errmsg); return (-1); } printf("ping_host_add() successn"); while (1) { if (ping_send(ping) < 0) { fprintf(stderr,"ping_send Failedn"); return (-1); } printf("ping_send() successn"); for (iter = ping_iterator_get(ping); iter != NULL; iter = ping_iterator_next(iter)) { char hostname[100]; double latency; unsigned int len; printf("ping_iterator_get() successn"); len = 100; ping_iterator_get_info(iter,PING_INFO_HOSTNAME,hostname,&len); len = sizeof(double); ping_iterator_get_info(iter,PING_INFO_LATENCY,&latency,&len); printf("hostname = %s,latency = %fn",latency); } sleep(1); } printf("exiting...n"); return (0); }

输出

anurag@anurag-PC:~$ sudo ./test ping_construct() success ping_host_add() success ping_send() success ping_iterator_get() success hostname = www.xively.com,latency = 233.666000 ping_send() success ping_iterator_get() success hostname = www.xively.com,latency = 234.360000 ping_send() success ping_iterator_get() success hostname = www.xively.com,latency = 234.076000 ping_send() success ping_iterator_get() success hostname = www.xively.com,latency = 231.761000 ping_send() success ping_iterator_get() success hostname = www.xively.com,latency = 235.085000 ^C

如果你想检查从你的Linux设备的互联网连接,如果您的ISP或目标不阻止ICMP数据包,libbing是很好的。 如果这些被阻止,您可以使用一些HTTP库来尝试从www.google.com或任何其他网站获取index.html页面,并检查是否成功

你不能立即阅读它,并且在执行结束时不打印。

这是显示的时刻

管道的缓冲区被填满或

管道关闭

您需要修改管道的属性

替换你的printf("%s",s);

n将刷新缓冲区,以便在执行printf命令后立即获得输出,并且不需要等到程序执行停止。

只需强制换行输出,然后stdout ,更改cmd

char *cmds = "ping -c 3 google.com | awk ' /icmp/ { printf("%s\n",$0); } '"; FILE *cmd = popen ( cmds,"r" );

它工作,由我自己测试。

其他方法将不起作用,因为问题是关于管道冲洗,而不是当前进程stdout刷新。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐