我是靠谱客的博主 矮小香菇,最近开发中收集的这篇文章主要介绍C++之编码实现ping的功能,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

## 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 <stdio.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <netdb.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netdb.h>
#include <time.h>
//check static device status
#define PACET_SIZE
4096
#define MAX_WAIT_TIME	3
#define MAX_NO_PACKETS	3
pid_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 now
char sendpacket[PACET_SIZE] = {''};
char recvpacket[PACET_SIZE] = {''};
struct sockaddr_in dest_addr;
struct sockaddr_in from;
struct timeval tvrecv;
/*******************************************************************************************************
Funtion: get_device_status
Description:get status of all device,through ping
Iput:pDevIp:device ip addr
Output:
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_fun
Description:ping device by ip
Iput:pDevIp:device ip addr
Output:
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] = {''};
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) failedn",pDevIp);
}
return iRet;
}
/*******************************************************************************************************
Funtion: ping_dev_by_icmp
Description:get status of static device,through ping
Iput:pDevIp:device ip addr
Output:
Return:0:connected,-1:disconnected
*******************************************************************************************************/
int ping_dev_by_icmp(PCHAR pDevIp)
{
int iRet = -1;
nsend = 0;
nreceived = 0;
memset(sendpacket,'',PACET_SIZE);
memset(recvpacket,'',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_PACKET
Description:send icmp packet
Iput:
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_PACKET
Description:receive icmp packet head
Iput:
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_UNPACK
Description:remove icmp packet head
Iput:
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_timeval
Description:one tineval - one timeval
Iput:
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_result
Description:
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_CHKSUM
Description:check
Iput:
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_PACK
Description:set icmp packet
Iput: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;
}


最后

以上就是矮小香菇为你收集整理的C++之编码实现ping的功能的全部内容,希望文章能够帮你解决C++之编码实现ping的功能所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(42)

评论列表共有 0 条评论

立即
投稿
返回
顶部