博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++之编码实现ping的功能
阅读量:4027 次
发布时间:2019-05-24

本文共 8479 字,大约阅读时间需要 28 分钟。

## ping_dev.h

#ifndef PING_DEV_H#define PING_DEV_H#include "typedef.h"INT32 get_device_status(PCHAR pDevIp);INT32 ping_fun(PCHAR pDevIp);int ping_dev_by_icmp(PCHAR pDevIp);int ping_dev_by_icmp_result();UINT16 ping_dev_by_icmp_cksum(UINT16 *addr, UINT32 len);int ping_dev_by_icmp_size(UINT32 pack_no);VOID ping_dev_by_icmp_send();VOID ping_dev_by_icmp_recv();int ping_dev_by_icmp_upack(PCHAR buf, UINT32 len);VOID ping_dev_by_icmp_timeval(struct timeval *out,struct timeval *in);#endif
## ping_dev.cpp

#include "ping_dev.h"#include "log.h"#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//check static device status#define PACET_SIZE 4096#define MAX_WAIT_TIME 3#define MAX_NO_PACKETS 3pid_t pid;int sockfd = -1 ,datalen = 56;int nsend = 0,nreceived = 0;static INT32 gDevPingFlag = -1; //-1:no device is pinging now, 0:some device is pinging nowchar sendpacket[PACET_SIZE] = {'\0'};char recvpacket[PACET_SIZE] = {'\0'};struct sockaddr_in dest_addr;struct sockaddr_in from;struct timeval tvrecv;/*******************************************************************************************************Funtion: get_device_statusDescription:get status of all device,through pingIput:pDevIp:device ip addrOutput:Return:0:connected,-1:disconnected*******************************************************************************************************/INT32 get_device_status(PCHAR pDevIp){ INT32 iRet = -1; if(gDevPingFlag == 0) return -1; if(pDevIp == NULL || strlen(pDevIp) <= 0) { LOG_MSG(LOG_ERR,"device ip is incorrect!\n"); return -1; } gDevPingFlag = 0; iRet = ping_fun(pDevIp); gDevPingFlag = -1; return iRet;}/*******************************************************************************************************Funtion: ping_funDescription:ping device by ipIput:pDevIp:device ip addrOutput:Return:0:connected,-1:disconnected*******************************************************************************************************/INT32 ping_fun(PCHAR pDevIp){ INT32 iRet = -1; if(pDevIp == NULL || strlen(pDevIp) <= 0) { return -1; }#if 0 char strPing[COMMON_CHAR_LEN] = {'\0'}; sprintf(strPing,"%s %s %s","ping",pDevIp,"-c 3 2>&1 >/dev/null"); iRet = SYSTEM(strPing);#endif iRet = ping_dev_by_icmp(pDevIp); if(0 != iRet) { //LOG_MSG(LOG_ERR,"ping device(%s) failed\n",pDevIp); } return iRet;}/*******************************************************************************************************Funtion: ping_dev_by_icmpDescription:get status of static device,through pingIput:pDevIp:device ip addrOutput:Return:0:connected,-1:disconnected*******************************************************************************************************/int ping_dev_by_icmp(PCHAR pDevIp){ int iRet = -1; nsend = 0; nreceived = 0; memset(sendpacket,'\0',PACET_SIZE); memset(recvpacket,'\0',PACET_SIZE); struct hostent *host; struct protoent *protocol; unsigned long inaddr = 01; int waittime = MAX_WAIT_TIME; int size = 20*1024; if((protocol = getprotobyname("icmp")) == NULL) { perror("getprotobyname"); return -1; } if((sockfd = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP)) < 0) { perror("socket error"); return -1; } //setuid(getuid()); setsockopt(sockfd,SOL_SOCKET,SO_RCVBUF,&size,sizeof(size)); bzero(&dest_addr,sizeof(dest_addr)); bzero(&from,sizeof(from)); dest_addr.sin_family = AF_INET; if((inaddr = inet_addr(pDevIp)) == INADDR_NONE) //is host name { if((host = gethostbyname(pDevIp)) == NULL) { perror("gethostbyname error"); return -1; } memcpy((char *)&dest_addr,(char *)&inaddr,host->h_length); } else //is ip addr { dest_addr.sin_addr.s_addr = inet_addr(pDevIp); } pid = getpid(); ping_dev_by_icmp_send(); ping_dev_by_icmp_recv(); iRet= ping_dev_by_icmp_result(); return iRet;}/*******************************************************************************************************Funtion: GET_STATIC_DEV_STATUS_SEND_PACKETDescription:send icmp packetIput:Output:Return:*******************************************************************************************************/VOID ping_dev_by_icmp_send(){ int packsize; while(nsend < MAX_NO_PACKETS) { nsend++; packsize = ping_dev_by_icmp_size(nsend); if(sendto(sockfd,sendpacket,packsize,0,(struct sockaddr *)&dest_addr,sizeof(dest_addr)) < 0) { perror("sendto error"); continue; } usleep(5); }}/*******************************************************************************************************Funtion: GET_STATIC_DEV_STATUS_RECV_PACKETDescription:receive icmp packet headIput:Output:Return:*******************************************************************************************************/VOID ping_dev_by_icmp_recv(){ int n; socklen_t fromlen; extern int errno; //signal(SIGALRM,GET_STATIC_DEV_STATUS_STATISTICS); fromlen = sizeof(from); int maxfds = 0; fd_set readfds; struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 5; while(nreceived < nsend) { FD_ZERO(&readfds); FD_SET(sockfd,&readfds); maxfds = sockfd + 1; n = select(maxfds,&readfds,NULL,NULL,&timeout); if(n <= 0) { close(sockfd); sockfd = -1; return ; } //alarm(MAX_WAIT_TIME); if((n = recvfrom(sockfd,recvpacket,sizeof(recvpacket),0,(struct sockaddr *)&from,&fromlen)) < 0) { return ; } gettimeofday(&tvrecv,NULL); if(ping_dev_by_icmp_upack(recvpacket,n) == -1) return; nreceived++; }}/*******************************************************************************************************Funtion: GET_STATIC_DEV_STATUS_UNPACKDescription:remove icmp packet headIput:Output:Return:0:success,-1:error*******************************************************************************************************/int ping_dev_by_icmp_upack(PCHAR buf, UINT32 len){ int i,iphdrlen; struct ip *ip; struct icmp *icmp; struct timeval *tvsend; double rtt; ip = (struct ip *)buf; iphdrlen = ip->ip_hl<<2; icmp = (struct icmp *)(buf + iphdrlen); len -= iphdrlen; if(len < 8) { return -1; } if((icmp->icmp_type == ICMP_ECHOREPLY) && (icmp->icmp_id == pid)) { tvsend = (struct timeval *)icmp->icmp_data; ping_dev_by_icmp_timeval(&tvrecv,tvsend); rtt = tvrecv.tv_sec * 1000 + tvrecv.tv_usec/1000; return 0; } else { return -1; }}/*******************************************************************************************************Funtion: ping_dev_by_icmp_timevalDescription:one tineval - one timevalIput:Output:Return:*******************************************************************************************************/VOID ping_dev_by_icmp_timeval(struct timeval *out,struct timeval *in){ if((out->tv_usec -= in->tv_usec) < 0) { --out->tv_sec; out->tv_usec += 1000000; } out->tv_sec -= in->tv_sec;}/*******************************************************************************************************Funtion: ping_dev_by_icmp_resultDescription:Iput:Output:Return:*******************************************************************************************************/int ping_dev_by_icmp_result(){ int iRet = -1; if(nsend == nreceived) { iRet = 0; } else { iRet = -1; } close(sockfd); sockfd = -1; return iRet;}/*******************************************************************************************************Funtion: GET_STATIC_DEV_STATUS_CAL_CHKSUMDescription:checkIput:Output:Return:*******************************************************************************************************/UINT16 ping_dev_by_icmp_cksum(UINT16 *addr, UINT32 len){ UINT32 nleft = len; UINT32 sum = 0; UINT16 *w = addr; UINT32 answer = 0; while(nleft > 1) { sum += *w++; nleft -= 2; } if(nleft == 1) { *(unsigned char *)(&answer) = *(unsigned char *)w; sum += answer; } sum = (sum>>16)+ (sum&0xffff); sum += (sum>>16); answer =~ sum; return answer;}/*******************************************************************************************************Funtion: GET_STATIC_DEV_STATUS_PACKDescription:set icmp packetIput:pack_no:Output:Return:*******************************************************************************************************/int ping_dev_by_icmp_size(UINT32 pack_no){ int i,packsize; struct icmp *icmp; struct timeval *tval; icmp = (struct icmp*)sendpacket; icmp->icmp_type = ICMP_ECHO; icmp->icmp_code = 0; icmp->icmp_cksum = 0; icmp->icmp_seq = pack_no; icmp->icmp_id = pid; packsize = 8 + datalen; tval = (struct timeval *)icmp->icmp_data; gettimeofday(tval,NULL); icmp->icmp_cksum = ping_dev_by_icmp_cksum((UINT16 *)icmp,packsize); return packsize;}

转载地址:http://icvbi.baihongyu.com/

你可能感兴趣的文章
Android环境搭建_转载
查看>>
JS操作SELECT表单大全,赋默认值,取值,增,删等
查看>>
浅谈BigDecimal类在电子商务中至关重要的地位!
查看>>
输出的数字的格式DecimalFormat的方法用途
查看>>
如何使用spring的作用域:
查看>>
Tomcat DBCP 连接池参数说明
查看>>
hibernate集合映射inverse和cascade详解
查看>>
使用SSH框架的好处
查看>>
attachEvent、addEventListener、detachEvent、removeEventListener
查看>>
flex myeclipse安装.
查看>>
hibernate中get 与 load 区别
查看>>
JSP文件下载及getOutputStream() has already been的解决
查看>>
Tomcat 6.0 开发配置小结
查看>>
FusionCharts 使用手记
查看>>
Struts,Spring,Hibernate优缺点
查看>>
用Spring更好地处理Struts动作三种整合
查看>>
spring中配置二级缓存
查看>>
Hibernate 查询语句HQL基本语法
查看>>
HIbernate查询
查看>>
小技巧要你命三千之:checkbox radio select 只读效果
查看>>