linux下另一种实现ping的方法
前面发了一篇:[全场景适应]linux C 实现ping功能-LinuxC程序-凯特网 (caterwang.cn),当时还取了一个名叫全场景,结果后来在ARM ubuntu 下被打脸了,失灵了。于是为了弥补这个缺憾,有了今天这篇文章。
实现方法有点low,但好在有效。以下为源代码
功能函数,这个是一个通用的调用脚本的函数,可以返回执行脚本命令后返回的信息
int execute_cmd (const char *p_cmd, char *p_result, unsigned int cmdTmOut, size_t &resLen) { int len = 0; fd_set readfd; time_t startTime = time (NULL); struct timeval tv; int selectRet = HRIM_OK; int systemRet = HRIM_OK; std::string runCmd = p_cmd; size_t res_len = 0; FILE * pPipe = popen (runCmd.c_str(), "r"); if (NULL == pPipe) { //cout << "popen() failed:"<< strerror(errno) << endl; systemRet = HRIM_ERR; return systemRet; } int fd = fileno (pPipe); //FILE描述符转化为FD while (true) { FD_ZERO (&readfd); FD_SET (fd, &readfd); fcntl (fd, F_SETFD, FD_CLOEXEC); /** Select Timeout Hardcode with 1 secs **/ tv.tv_sec = cmdTmOut; tv.tv_usec = 0; selectRet = select (fd + 1, &readfd, NULL, NULL, &tv); if (selectRet < HRIM_OK) { //cout << "select() failed " << strerror(errno) << endl; snprintf (p_result, HRI_CMD_RES_LEN, "ExecuteCmd select error!"); systemRet = HRIM_OK; break; } else if (selectRet == HRIM_OK) { //cout << "select() timeout" << endl; snprintf (p_result, HRI_CMD_RES_LEN, "ExecuteCmd:[%s] success!", p_cmd); systemRet = HRIM_OK; break; } else { //cout << "Data is available now" <<endl; if (FD_ISSET (fd, &readfd) ) { //if (fgets (buf, sizeof (buf), pPipe) != NULL ) if (fread ( p_result, sizeof (char), HRI_CMD_RES_LEN, pPipe) > 0) { //cout << buf; //strBuf << buf; res_len = strlen (p_result); if (res_len <= 0) { //snprintf (p_result, HRI_CMD_RES_LEN, "RunCmd return empty"); snprintf (p_result, HRI_CMD_RES_LEN, "ExecuteCmd:[%s] success!", p_cmd); systemRet = HRIM_OK; break; } len = (res_len - 1); //数组索引从0开始 if ( (len > 0) && ( (p_result[len] == '\r') || (p_result[len] == '\n') ) ) { p_result[len] = '\0'; //去除结果中的回车换行符 } systemRet = HRIM_OK; break; } else /** No Problem if there is no data ouput by runCmd **/ { //systemRet = -1; // cout << "fread() failed " << strerror(errno) << endl; //snprintf (p_result, HRI_CMD_RES_LEN, "RunCmd No return value"); snprintf (p_result, HRI_CMD_RES_LEN, "ExecuteCmd:[%s] success!", p_cmd); systemRet = HRIM_OK; break; } } else { // cout << "FD_ISSET() failed " << strerror(errno) << endl; snprintf (p_result, HRI_CMD_RES_LEN, "ExecuteCmd:[%s] failed, Error:[%s]", p_cmd, strerror (errno) ); systemRet = HRIM_OK; break; } } /** Check the Script-timeout **/ if ( (startTime + cmdTmOut) < time (NULL) ) { // cout<<"Script Timeout"<<endl; snprintf (p_result, HRI_CMD_RES_LEN, "ExecuteCmd:[%s] Timeout!", p_cmd); systemRet = HRIM_ERR; break ; } } pclose (pPipe); pPipe = NULL; resLen = res_len; return systemRet; }
以下是调用以上函数实现ping功能的函数
// int FaceCenter::hri_Ping( char *ips, int timeout) { int ret =-1; char msg[1024] = {0}; char cmd[1024] = {0}; size_t resLen = 0; snprintf(cmd, 1024, "ping %s -c 2 | grep received | awk 'NR==1{print $4}'|tr -d ','",ips); execute_cmd(cmd, msg, timeout, resLen); if(resLen > 0) { ret = (atoi(msg)==2 ? 0 : 1); //ping 通返回0,ping 不通返回1 } return ret; }
以下是实现原理简单说明
凯特网版权声明:以上内容允许转载,但请注明出处,谢谢!