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;
}以下是实现原理简单说明

凯特网版权声明:以上内容允许转载,但请注明出处,谢谢!
