我必须从C++代码调用ping。我希望轻松地读取输出,以便进一步利用。
我提出了两个解决方案:
我喜欢后者,但我没有找到任何明显是标准解决方案的解决方案。
你会怎么做?
iyfjxgzm1#
从教育的Angular 来看,调用外部二进制文件是非常不可取的。尤其是对于发送ICMP回应请求这样的简单任务,您应该学习一些套接字。
aor9mmx12#
# 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; }
bqf10yzr3#
我会选择你的第一个选择。Linux是围绕这样一个概念构建的,即拥有专门的小型应用程序,这些应用程序可以很好地完成一件事,即与管道进行通信。你的应用程序不应该包括一个库来实现ping,因为已经有一个内置的命令来实现它,而且它工作得很好!
91zkwejq4#
Check out BusyBox's source for 'ping' - you can use the ping4 and ping6 functions. Just be mindful of the GPL.
ping4
ping6
Spawning 'ping' should work too - check out popen(2) for a simpler API that also runs a shell. If it's a problem, pipe + fork + exec should work.
popen(2)
pipe
fork
exec
ds97pgxw5#
https://github.com/octo/liboping怎么样?
# include <oping.h> int main(){ // run ping 100times for (uint32_t i=0; i< 100; i++){ pingobj_t * pingObj = ping_construct(); ping_host_add(pingObj, "www.gmx.de"); auto startTime = std::chrono::high_resolution_clock::now(); auto ret = ping_send(pingObj); auto endTime = std::chrono::high_resolution_clock::now(); if (ret > 0){ auto duration = (double)std::chrono::duration_cast<std::chrono::microseconds>(endTime - startTime).count()/1000.0; std::cout << "success -- ping in " << duration << "ms" << std::endl; } else { std::cout << "failed" << std::endl; } ping_destroy(pingObj); // wait 1sec std::this_thread::sleep_for(std::chrono::milliseconds (1000)); } }
liboping应该出现在大多数Linux系统中
liboping
sudo apt install liboping-dev
k10s72fa6#
我成功地做到了这一点:
我使用Popen,它基本上创建了一个管道、叉子和exec,然后,如果我需要的话,我可以用plose等待。
6条答案
按热度按时间iyfjxgzm1#
从教育的Angular 来看,调用外部二进制文件是非常不可取的。尤其是对于发送ICMP回应请求这样的简单任务,您应该学习一些套接字。
aor9mmx12#
bqf10yzr3#
我会选择你的第一个选择。Linux是围绕这样一个概念构建的,即拥有专门的小型应用程序,这些应用程序可以很好地完成一件事,即与管道进行通信。你的应用程序不应该包括一个库来实现ping,因为已经有一个内置的命令来实现它,而且它工作得很好!
91zkwejq4#
Check out BusyBox's source for 'ping' - you can use the
ping4
andping6
functions. Just be mindful of the GPL.Spawning 'ping' should work too - check out
popen(2)
for a simpler API that also runs a shell. If it's a problem,pipe
+fork
+exec
should work.ds97pgxw5#
https://github.com/octo/liboping怎么样?
liboping
应该出现在大多数Linux系统中sudo apt install liboping-dev
)k10s72fa6#
我成功地做到了这一点:
我使用Popen,它基本上创建了一个管道、叉子和exec,然后,如果我需要的话,我可以用plose等待。