什么是最好的方法来ping在Linux下的C + +?

我必须从c ++代码调用ping。我想要轻松读取输出以进一步利用。

我已经想出了两个解决scheme:

  • 使用叉子和pipe道,将ping输出redirect到pipe道,然后parsing它
  • find一个适合直接使用ping(ip_addresss)函数的库

我希望后者,但我没有find任何明显的标准解决scheme。

你会怎么做?

我会选择你的第一个选择。 Linux是建立在小型专业应用程序的基础之上的,这个应用程序可以很好地与管道沟通。 你的应用程序不应该包括一个库来实现ping,因为已经有一个内置的命令来做到这一点,它的工作非常好!

从教育的角度来看,调用外部二进制是非常不可取的 。 特别是对于一个简单的任务,例如发送一个ICMP回应请求,你应该学习一些套接字。

#include <fcntl.h> #include <errno.h> #include <sys/socket.h> #include <resolv.h> #include <netdb.h> #include <netinet/in.h> #include <netinet/ip_icmp.h> #define PACKETSIZE 64 struct packet { struct icmphdr hdr; char msg[PACKETSIZE-sizeof(struct icmphdr)]; }; int pid=-1; struct protoent *proto=NULL; int cnt=1; /*--------------------------------------------------------------------*/ /*--- checksum - standard 1s complement checksum ---*/ /*--------------------------------------------------------------------*/ unsigned short checksum(void *b, int len) { unsigned short *buf = b; unsigned int sum=0; unsigned short result; for ( sum = 0; len > 1; len -= 2 ) sum += *buf++; if ( len == 1 ) sum += *(unsigned char*)buf; sum = (sum >> 16) + (sum & 0xFFFF); sum += (sum >> 16); result = ~sum; return result; } /*--------------------------------------------------------------------*/ /*--- ping - Create message and send it. ---*/ /* return 0 is ping Ok, return 1 is ping not OK. ---*/ /*--------------------------------------------------------------------*/ int ping(char *adress) { const int val=255; int i, sd; struct packet pckt; struct sockaddr_in r_addr; int loop; struct hostent *hname; struct sockaddr_in addr_ping,*addr; pid = getpid(); proto = getprotobyname("ICMP"); hname = gethostbyname(adress); bzero(&addr_ping, sizeof(addr_ping)); addr_ping.sin_family = hname->h_addrtype; addr_ping.sin_port = 0; addr_ping.sin_addr.s_addr = *(long*)hname->h_addr; addr = &addr_ping; sd = socket(PF_INET, SOCK_RAW, proto->p_proto); if ( sd < 0 ) { perror("socket"); return 1; } if ( setsockopt(sd, SOL_IP, IP_TTL, &val, sizeof(val)) != 0) { perror("Set TTL option"); return 1; } if ( fcntl(sd, F_SETFL, O_NONBLOCK) != 0 ) { perror("Request nonblocking I/O"); return 1; } for (loop=0;loop < 10; loop++) { int len=sizeof(r_addr); if ( recvfrom(sd, &pckt, sizeof(pckt), 0, (struct sockaddr*)&r_addr, &len) > 0 ) { return 0; } bzero(&pckt, sizeof(pckt)); pckt.hdr.type = ICMP_ECHO; pckt.hdr.un.echo.id = pid; for ( i = 0; i < sizeof(pckt.msg)-1; i++ ) pckt.msg[i] = i+'0'; pckt.msg[i] = 0; pckt.hdr.un.echo.sequence = cnt++; pckt.hdr.checksum = checksum(&pckt, sizeof(pckt)); if ( sendto(sd, &pckt, sizeof(pckt), 0, (struct sockaddr*)addr, sizeof(*addr)) <= 0 ) perror("sendto"); usleep(300000); } return 1; } /*--------------------------------------------------------------------*/ /*--- main - look up host and start ping processes. ---*/ /*--------------------------------------------------------------------*/ int main(int argc, char *argv[]) { if (ping("www.google.com")) printf("Ping is not OK. \n"); else printf("Ping is OK. \n"); return 0; } 

你可以尝试使用这个代码 。

查看BusyBox的源代码是否可以ping通 – 您可以使用ping6ping6功能。 只要注意GPL。

产卵'平'也应该工作 – 检查popen(2)一个更简单的API,也运行一个shell。 如果有问题, pipe + fork + exec应该可以工作。

我设法做到这一点:

我使用popen,基本上创建一个管道,叉子和执行然后,如果我需要,我可以等待pclose。