c++ 实现ping
//头文件
- /*
- * File: CPing.h
- * Author: jaylong35
- *
- * Created on 2011年1月26日, 下午3:12
- */
- #ifndef CPING_H
- #define CPING_H
- #include <string>
- #include <signal.h>
- #include <arpa/inet.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <unistd.h>
- #include <netinet/in.h>
- #include <netinet/ip.h>
- #include <netinet/ip_icmp.h>
- #include <netdb.h>
- #include <setjmp.h>
- #include <errno.h>
- #include <sys/time.h>
- using namespace std;
- #define PACKET_SIZE 4096
- #define SEND_DATA_LEN 56
- #define ERROR -1
- #define SUCCESS 1
- #define MAX_WAIT_TIME 5
- #define MAX_NO_PACKETS 100
- class CPing
- {
- public:
- CPing(const char * ip, int timeout);
- CPing(const CPing& orig);
- virtual ~CPing();
- private:
- std::string m_strIp;
- int m_nTimeOut;
- int m_nPkgLen;
- double m_dAvgTime;
- double m_dFasterResponseTime;
- double m_dLowerResponseTime;
- double m_dTotalResponseTimes;
- int m_nSend;
- int m_nRecv;
- int m_nSocketfd;
- pid_t m_Pid;
- struct sockaddr_in m_dest_addr;
- struct sockaddr_in m_from;
- char m_sendpacket[PACKET_SIZE];
- char m_recvpacket[PACKET_SIZE];
- struct timeval m_tvrecv;
- public:
- enum
- {
- PING_FAILED,
- PING_SUCCEED
- };
- std::string GetIp() { return m_strIp; }
- int GetTimeOut() { return m_nTimeOut; }
- int GetPkgLen() { return m_nPkgLen; }
- void SetIp(const char * ip) { m_strIp = ip; }
- void SetTimeOut(int timeout) { m_nTimeOut = timeout; }
- void SetPkgLen(int pkglen) { m_nPkgLen = pkglen; }
- double GetAvgResponseTime() { return m_dAvgTime; }
- double GetFasterResponseTime() { return m_dFasterResponseTime; }
- double GetLowerResponseTime() { return m_dLowerResponseTime; }
- unsigned int GetPingStatus();
- static unsigned short cal_chksum(unsigned short *addr, int len);
- void statistics();
- int pack(int pack_no);
- void send_packet(int num);
- void recv_packet(void);
- int unpack(char *buf, int len);
- void tv_sub(struct timeval *out, struct timeval *in);
- bool ping(int times);
- };
- #endif /* CPING_H
cpp文件
- /*
- * File: CPing.cpp
- * Author: jaylong35
- *
- * Created on 2011年1月26日, 下午3:12
- */
- #include "CPing.h"
- CPing::CPing(const char * ip, int timeout)
- {
- m_strIp = ip;
- m_nTimeOut = timeout;
- m_nSend = 0;
- m_nRecv = 0;
- m_nSocketfd = 0;
- }
- CPing::CPing(const CPing& orig)
- {
- }
- CPing::~CPing()
- {
- }
- bool CPing::ping(int times)
- {
- struct hostent *host;
- struct protoent *protocol;
- unsigned long inaddr = 0l;
- int size = 50 * 1024;
- if ((protocol = getprotobyname("icmp")) == NULL)
- {
- perror("getprotobyname");
- return false;
- }
- /*生成使用ICMP的原始套接字,这种套接字只有root才能生成*/
- if ((m_nSocketfd = socket(AF_INET, SOCK_RAW, protocol->p_proto)) < 0)
- {
- perror("socket error");
- exit(1);
- }
- /* 回收root权限,设置当前用户权限*/
- setuid(getuid());
- /*扩大套接字接收缓冲区到50K这样做主要为了减小接收缓冲区溢出的
- 的可能性,若无意中ping一个广播地址或多播地址,将会引来大量应答*/
- setsockopt(m_nSocketfd, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size));
- bzero(&m_dest_addr, sizeof (m_dest_addr));
- m_dest_addr.sin_family = AF_INET;
- /*判断是主机名还是ip地址*/
- if (inaddr = inet_addr(m_strIp.c_str()) == INADDR_NONE)
- {
- if ((host = gethostbyname(m_strIp.c_str())) == NULL) /*是主机名*/
- {
- perror("gethostbyname error");
- exit(1);
- }
- memcpy((char *) &m_dest_addr.sin_addr, host->h_addr, host->h_length);
- }
- else /*是ip地址*/
- memcpy((char *) &m_dest_addr, (char *) &inaddr, host->h_length);
- /*获取main的进程id,用于设置ICMP的标志符*/
- m_Pid = getpid();
- printf("PING %s(%s): %d bytes data in ICMP packets./n", m_strIp.c_str(),
- inet_ntoa(m_dest_addr.sin_addr), SEND_DATA_LEN);
- int i = 0;
- while(i < times)
- {
- i++;
- send_packet(1); /*发送所有ICMP报文*/
- recv_packet(); /*接收所有ICMP报文*/
- }
- statistics(); /*进行统计*/
- }
- unsigned short CPing::cal_chksum(unsigned short *addr, int len)
- {
- int nleft=len;
- int sum=0;
- unsigned short *w=addr;
- unsigned short 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;
- }
- void CPing::tv_sub(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;
- }
- void CPing::statistics()
- {
- printf("/n--------------------PING statistics-------------------/n");
- printf("%d packets transmitted, %d received , %%%d lost/n", m_nSend, m_nRecv,
- (m_nSend - m_nRecv) / m_nSend * 100);
- close(m_nSocketfd);
- m_nTimeOut = m_nSend - m_nRecv;
- m_dAvgTime = m_dTotalResponseTimes/m_nRecv;
- return;
- }
- /*设置ICMP报头*/
- int CPing::pack(int pack_no)
- {
- int packsize;
- struct icmp *icmp;
- struct timeval *tval;
- icmp = (struct icmp*) m_sendpacket;
- icmp->icmp_type = ICMP_ECHO;
- icmp->icmp_code = 0;
- icmp->icmp_cksum = 0;
- icmp->icmp_seq = pack_no;
- icmp->icmp_id = m_Pid;
- packsize = 8 + SEND_DATA_LEN;
- tval = (struct timeval *) icmp->icmp_data;
- gettimeofday(tval, NULL); /*记录发送时间*/
- icmp->icmp_cksum = cal_chksum((unsigned short *) icmp, packsize); /*校验算法*/
- return packsize;
- }
- /*发送三个ICMP报文*/
- void CPing::send_packet(int num)
- {
- if(num > MAX_NO_PACKETS)
- num = MAX_NO_PACKETS;
- int packetsize;
- int i = 0;
- while (i < num)
- {
- i++;
- m_nSend++;
- packetsize = pack(m_nSend); /*设置ICMP报头*/
- if (sendto(m_nSocketfd, m_sendpacket, packetsize, 0,
- (struct sockaddr *) &m_dest_addr, sizeof (m_dest_addr)) < 0)
- {
- perror("sendto error");
- continue;
- }
- sleep(1); /*每隔一秒发送一个ICMP报文*/
- }
- }
- /*接收所有ICMP报文*/
- void CPing::recv_packet()
- {
- int n,fromlen;
- //signal(SIGALRM, statistics);
- fromlen = sizeof (m_from);
- while (m_nRecv < m_nSend)
- {
- alarm(MAX_WAIT_TIME);
- if ((n = recvfrom(m_nSocketfd, m_recvpacket, sizeof (m_recvpacket), 0,
- (struct sockaddr *) &m_from, (socklen_t *)&fromlen)) < 0)
- {
- if (errno == EINTR)continue;
- perror("recvfrom error");
- continue;
- }
- gettimeofday(&m_tvrecv, NULL); /*记录接收时间*/
- if (unpack(m_recvpacket, n) == -1)
- continue;
- m_nRecv++;
- }
- }
- /*剥去ICMP报头*/
- int CPing::unpack(char *buf,int len)
- {
- int i,iphdrlen;
- struct ip *ip;
- struct icmp *icmp;
- struct timeval *tvsend;
- double rtt;
- ip = (struct ip *) buf;
- iphdrlen = ip->ip_hl << 2; /*求ip报头长度,即ip报头的长度标志乘4*/
- icmp = (struct icmp *) (buf + iphdrlen); /*越过ip报头,指向ICMP报头*/
- len -= iphdrlen; /*ICMP报头及ICMP数据报的总长度*/
- if (len < 8) /*小于ICMP报头长度则不合理*/
- {
- printf("ICMP packets/'s length is less than 8/n");
- return -1;
- }
- /*确保所接收的是我所发的的ICMP的回应*/
- if ((icmp->icmp_type == ICMP_ECHOREPLY) && (icmp->icmp_id == m_Pid))
- {
- tvsend = (struct timeval *) icmp->icmp_data;
- tv_sub(&m_tvrecv, tvsend); /*接收和发送的时间差*/
- rtt = m_tvrecv.tv_sec * 1000 + m_tvrecv.tv_usec / 1000; /*以毫秒为单位计算rtt*/
- m_dTotalResponseTimes += rtt;
- if(m_dFasterResponseTime == -1)
- {
- m_dFasterResponseTime = rtt;
- }
- else if(m_dFasterResponseTime > rtt)
- {
- m_dFasterResponseTime = rtt;
- }
- if(m_dLowerResponseTime == -1)
- {
- m_dLowerResponseTime = rtt;
- }
- else if(m_dLowerResponseTime < rtt)
- {
- m_dLowerResponseTime = rtt;
- }
- /*显示相关信息*/
- printf("%d/tbyte from %s/t: icmp_seq=%u/tttl=%d/trtt=%.3f/tms/n",
- len,
- inet_ntoa(m_from.sin_addr),
- icmp->icmp_seq,
- ip->ip_ttl,
- rtt);
- }
- else return -1;
- }
调用
- #include "CPing.h"
- int main()
- {
- CPing ping("192.168.10.48",100);
- ping.ping(20);
- }
运行结果
PING 192.168.10.48(0.0.0.0): 56 bytes data in ICMP packets.表明
64 byte from 127.0.0.1 : icmp_seq=1 ttl=64 rtt=1000.000 ms
64 byte from 127.0.0.1 : icmp_seq=2 ttl=64 rtt=1001.000 ms
64 byte from 127.0.0.1 : icmp_seq=3 ttl=64 rtt=1001.000 ms
64 byte from 127.0.0.1 : icmp_seq=4 ttl=64 rtt=1001.000 ms
64 byte from 127.0.0.1 : icmp_seq=5 ttl=64 rtt=1001.000 ms
64 byte from 127.0.0.1 : icmp_seq=6 ttl=64 rtt=1002.000 ms
64 byte from 127.0.0.1 : icmp_seq=7 ttl=64 rtt=1001.000 ms
64 byte from 127.0.0.1 : icmp_seq=8 ttl=64 rtt=1002.000 ms
64 byte from 127.0.0.1 : icmp_seq=9 ttl=64 rtt=1002.000 ms
64 byte from 127.0.0.1 : icmp_seq=10 ttl=64 rtt=1000.000 ms
64 byte from 127.0.0.1 : icmp_seq=11 ttl=64 rtt=1001.000 ms
64 byte from 127.0.0.1 : icmp_seq=12 ttl=64 rtt=1001.000 ms
64 byte from 127.0.0.1 : icmp_seq=13 ttl=64 rtt=1001.000 ms
64 byte from 127.0.0.1 : icmp_seq=14 ttl=64 rtt=1000.000 ms
64 byte from 127.0.0.1 : icmp_seq=15 ttl=64 rtt=1001.000 ms
64 byte from 127.0.0.1 : icmp_seq=16 ttl=64 rtt=1001.000 ms
64 byte from 127.0.0.1 : icmp_seq=17 ttl=64 rtt=1001.000 ms
64 byte from 127.0.0.1 : icmp_seq=18 ttl=64 rtt=1002.000 ms
64 byte from 127.0.0.1 : icmp_seq=19 ttl=64 rtt=1001.000 ms
64 byte from 127.0.0.1 : icmp_seq=20 ttl=64 rtt=1001.000 ms
--------------------PING statistics-------------------
20 packets transmitted, 20 received , %0 lost
按 [Enter] 键关闭终端...
更新最新可用版本
因为很多朋友都要一个可用版本,所以今天在这里更新一下上面的程序
新版本的程序如下
.h
- /*
- * File: CPing.h
- * Author: scotte.ye
- *
- * Created on 2011年1月26日, 下午3:12
- */
- #ifndef CPING_H
- #define CPING_H
- #include <string>
- #include <signal.h>
- #include <arpa/inet.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <unistd.h>
- #include <netinet/in.h>
- #include <netinet/ip.h>
- #include <netinet/ip_icmp.h>
- #include <netdb.h>
- #include <setjmp.h>
- #include <errno.h>
- #include <sys/time.h>
- using namespace std;
- #define PACKET_SIZE 4096
- #define SEND_DATA_LEN 56
- #define ERROR -1
- #define SUCCESS 1
- #define MAX_WAIT_TIME 20
- #define MAX_NO_PACKETS 4
- class CPing
- {
- public:
- CPing(const char * ip, int timeout);
- CPing(const CPing& orig);
- virtual ~CPing();
- private:
- std::string m_strIp;
- std::string m_Ip;
- int m_nTimeOut;
- int m_nPkgLen;
- double m_dAvgTime;
- double m_dFasterResponseTime;
- double m_dLowerResponseTime;
- double m_dTotalResponseTimes;
- int m_nSend;
- int m_nRecv;
- int m_nSocketfd;
- pid_t m_Pid;
- struct sockaddr_in m_dest_addr;
- struct sockaddr_in m_from;
- char m_sendpacket[PACKET_SIZE];
- char m_recvpacket[PACKET_SIZE];
- struct timeval m_tvrecv;
- bool m_bTimeOut;
- //add by scotte.ye 2011-07-27
- int m_nMaxTimeWait;
- int m_nMaxTestpkg;
- public:
- enum
- {
- PING_FAILED,
- PING_SUCCEED
- };
- void SetMaxTimeWait(int nMaxTimeWait) { m_nMaxTimeWait = nMaxTimeWait; }
- void SetMaxTestpkg(int nMaxTestpkg) { m_nMaxTestpkg = nMaxTestpkg; }
- void SetPingManager(CPingManager * pPingManager) { m_pPingManager = pPingManager; }
- int GetSuccessTimes() { return m_nRecv; }
- std::string GetIp() { return m_Ip; }
- int GetTimeOut() { return m_nTimeOut; }
- int GetPkgLen() { return m_nPkgLen; }
- void SetIp(const char * ip) { m_strIp = ip; }
- void SetTimeOut(int timeout) { m_nTimeOut = timeout; }
- void SetPkgLen(int pkglen) { m_nPkgLen = pkglen; }
- double GetAvgResponseTime() { return m_dAvgTime; }
- double GetFasterResponseTime() { return m_dFasterResponseTime; }
- double GetLowerResponseTime() { return m_dLowerResponseTime; }
- unsigned int GetPingStatus();
- static unsigned short cal_chksum(unsigned short *addr, int len);
- //void statistics(int sig);
- int pack(int pack_no);
- void send_packet(void);
- void recv_packet(void);
- int unpack(char *buf, int len);
- void tv_sub(struct timeval *out, struct timeval *in);
- bool ping(int times);
- void statistics(int sig);
- bool CreateSocket();
- bool CloseSocket();
- //double ping_m();
- };
- #endif /* CPING_H */
cpp
- /*
- * File: CPing.cpp
- * Author: scotte.ye
- *
- * Created on 2011年1月26日, 下午3:12
- */
- #include "CPing.h"
- #include "CPingManager.h"
- #include "include/Log/CLog.h"
- #include <sys/types.h>
- #include <fcntl.h>
- #define gettid() syscall(224)
- void CPing::statistics(int sig)
- {
- printf("------statistics------\n");
- printf("%d packets transmitted, %d received , %%%d lost\n", m_nSend, m_nRecv,
- (m_nSend - m_nRecv) / m_nSend * 100);
- //close(m_nSocketfd);
- m_nTimeOut = m_nSend - m_nRecv;
- m_dAvgTime = m_dTotalResponseTimes/m_nRecv;
- // m_bTimeOut = true;
- }
- CPing::CPing(const char * ip, int timeout)
- {
- m_strIp = ip;
- m_Ip = ip;
- m_nTimeOut = 0;
- m_nSend = 0;
- m_nRecv = 0;
- m_nSocketfd = 0;
- m_dFasterResponseTime = -1;
- m_dLowerResponseTime = -1;
- m_dAvgTime = -1;
- m_dTotalResponseTimes = 0;
- m_pPingManager = NULL;
- if(timeout > MAX_WAIT_TIME)
- m_nMaxTimeWait = MAX_WAIT_TIME;
- else
- m_nMaxTimeWait = timeout;
- m_nMaxTestpkg = MAX_NO_PACKETS;
- }
- CPing::CPing(const CPing& orig)
- {
- }
- CPing::~CPing()
- {
- CloseSocket();
- }
- bool CPing::CreateSocket()
- {
- CloseSocket();
- struct hostent hostinfo,*host;
- char buf[2048];
- struct protoent *protocol;
- unsigned long inaddr = 0l;
- int size = 50 * 1024;
- if ((protocol = getprotobyname("icmp")) == NULL)
- {
- printf("CreateSocket: getprotobyname failed:%d\n",errno);
- return false;
- }
- /*生成使用ICMP的原始套接字,这种套接字只有root才能生成*/
- if ((m_nSocketfd = socket(AF_INET, SOCK_RAW, protocol->p_proto)) < 0)
- {
- printf("CreateSocket: create socket failed:%d\n",errno);
- return false;
- }
- /* 回收root权限,设置当前用户权限*/
- setuid(getuid());
- /*扩大套接字接收缓冲区到50K这样做主要为了减小接收缓冲区溢出的
- 的可能性,若无意中ping一个广播地址或多播地址,将会引来大量应答*/
- int nRet = setsockopt(m_nSocketfd, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size));
- if(nRet != 0)
- {
- printf("CreateSocket: set socket receive buf failed:%d\n",errno);
- return false;
- }
- bzero(&m_dest_addr, sizeof (m_dest_addr));
- m_dest_addr.sin_family = AF_INET;
- /*判断是主机名还是ip地址*/
- if ((inaddr = inet_addr(m_strIp.c_str())) == INADDR_NONE)
- {
- int nret;
- gethostbyname_r(m_strIp.c_str(), &hostinfo, buf, sizeof(buf), &host, &nret);
- if (nret != 0) /*是主机名*/
- {
- printf("CreateSocket: gethostbyname error %s failed:%d\n",m_strIp.c_str(),errno);
- return false;
- }
- memcpy((char *) &m_dest_addr.sin_addr, host->h_addr, host->h_length);
- }
- else /*是ip地址*/
- memcpy((char *) &m_dest_addr.sin_addr, (char *) &inaddr, sizeof(inaddr));
- m_Ip = inet_ntoa(m_dest_addr.sin_addr);
- return true;
- }
- bool CPing::CloseSocket()
- {
- if(m_nSocketfd !=0)
- close(m_nSocketfd);
- m_nSocketfd = 0;
- return true;
- }
- bool CPing::ping(int times)
- {
- int i = 0;
- while(i < times)
- {
- bool bRet = CreateSocket();
- if(!bRet)
- {
- printf("ping: create socket falied!\n");
- return false;
- }
- /*获取main的进程id,用于设置ICMP的标志符*/
- int nh = gettid();
- nh = nh<<8;
- time_t t;
- time(&t);
- int nt = t;
- nh = nh&0xff00;
- nt = nt&0xff;
- m_Pid = nt|nh;
- printf("PING %s(%s): %d bytes data in ICMP packets.\n", m_strIp.c_str(),
- m_Ip.c_str(), SEND_DATA_LEN);
- i++;
- m_nSend = 0;
- m_nRecv = 0;
- send_packet(); /*发送所有ICMP报文*/
- recv_packet(); /*接收所有ICMP报文*/
- //statistics(SIGALRM); /*进行统计*/
- if(m_nRecv > 0)
- break;
- }
- m_bTimeOut = false;
- if(m_nRecv > 0)
- {
- m_nTimeOut = m_nSend - m_nRecv;
- m_dAvgTime = m_dTotalResponseTimes/m_nRecv;
- }
- else
- {
- m_nTimeOut = m_nSend;
- m_dAvgTime = -1;
- return false;
- }
- return true;
- }
- unsigned short CPing::cal_chksum(unsigned short *addr, int len)
- {
- int nleft=len;
- int sum=0;
- unsigned short *w=addr;
- unsigned short 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;
- }
- void CPing::tv_sub(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;
- }
- /*设置ICMP报头*/
- int CPing::pack(int pack_no)
- {
- int packsize;
- struct icmp *icmp;
- struct timeval *tval;
- icmp = (struct icmp*) m_sendpacket;
- icmp->icmp_type = ICMP_ECHO;
- icmp->icmp_code = 0;
- icmp->icmp_cksum = 0;
- icmp->icmp_seq = pack_no;
- icmp->icmp_id = m_Pid;
- packsize = 8 + SEND_DATA_LEN;
- tval = (struct timeval *) icmp->icmp_data;
- gettimeofday(tval, NULL); /*记录发送时间*/
- icmp->icmp_cksum = cal_chksum((unsigned short *) icmp, packsize); /*校验算法*/
- return packsize;
- }
- /*发送三个ICMP报文*/
- void CPing::send_packet()
- {
- int packetsize;
- while (m_nSend < m_nMaxTestpkg)
- {
- m_nSend++;
- packetsize = pack(m_nSend); /*设置ICMP报头*/
- if (sendto(m_nSocketfd, m_sendpacket, packetsize, 0,
- (struct sockaddr *) &m_dest_addr, sizeof (m_dest_addr)) < 0)
- {
- printf("send_packet: send error :%d\n",errno);
- continue;
- }
- usleep(2); /*每隔一秒发送一个ICMP报文*/
- }
- }
- /*接收所有ICMP报文*/
- void CPing::recv_packet()
- {
- int n,fromlen;
- while(m_nRecv < m_nSend)
- {
- struct timeval timeo;
- fd_set readfds;
- FD_ZERO(&readfds);
- FD_SET(m_nSocketfd,&readfds);
- int maxfds = m_nSocketfd +1;
- timeo.tv_sec = m_nMaxTimeWait;
- timeo.tv_usec = 0;
- n = select(maxfds,&readfds,NULL,NULL,&timeo);
- if(n == 0)
- {
- printf("recv_packet: select time out :%d",errno);
- return ;
- }
- else if(n < 0)
- {
- printf("recv_packet: select error :%d",errno);
- if(errno == EINTR)
- {
- printf("recv_packet: select error :%d",errno);
- continue;
- }
- else
- {
- printf("recv_packet: select error :%d",errno);
- return ;
- }
- }
- if ((n = recvfrom(m_nSocketfd, m_recvpacket, sizeof (m_recvpacket), 0,
- (struct sockaddr *) &m_from, (socklen_t *)&fromlen)) <= 0)
- {
- printf("recv_packet: recv error :%d",errno);
- return;
- }
- gettimeofday(&m_tvrecv, NULL); /*记录接收时间*/
- if (unpack(m_recvpacket, n) == -1)
- {
- continue;
- }
- m_nRecv++;
- }
- //return ;
- }
- /*剥去ICMP报头*/
- int CPing::unpack(char *buf,int len)
- {
- int i,iphdrlen;
- struct ip *ip;
- struct icmp *icmp;
- struct timeval *tvsend;
- double rtt;
- ip = (struct ip *) buf;
- iphdrlen = ip->ip_hl << 2; /*求ip报头长度,即ip报头的长度标志乘4*/
- icmp = (struct icmp *) (buf + iphdrlen); /*越过ip报头,指向ICMP报头*/
- len -= iphdrlen; /*ICMP报头及ICMP数据报的总长度*/
- if (len < 8) /*小于ICMP报头长度则不合理*/
- {
- printf( "ICMP packets\'s length is less than 8");
- return -1;
- }
- /*确保所接收的是我所发的的ICMP的回应*/
- if ((icmp->icmp_type == ICMP_ECHOREPLY) && (icmp->icmp_id == m_Pid)&&(m_Ip == inet_ntoa(m_from.sin_addr)))
- {
- tvsend = (struct timeval *) icmp->icmp_data;
- tv_sub(&m_tvrecv, tvsend); /*接收和发送的时间差*/
- rtt = m_tvrecv.tv_sec * 1000 + m_tvrecv.tv_usec / 1000; /*以毫秒为单位计算rtt*/
- m_dTotalResponseTimes += rtt;
- if(m_dFasterResponseTime == -1)
- {
- m_dFasterResponseTime = rtt;
- }
- else if(m_dFasterResponseTime > rtt)
- {
- m_dFasterResponseTime = rtt;
- }
- if(m_dLowerResponseTime == -1)
- {
- m_dLowerResponseTime = rtt;
- }
- else if(m_dLowerResponseTime < rtt)
- {
- m_dLowerResponseTime = rtt;
- }
- /*显示相关信息*/
- printf("%d\tbyte from %s\t: icmp_seq=%u\tttl=%d\trtt=%.3f\tms\n",
- len,
- inet_ntoa(m_from.sin_addr),
- icmp->icmp_seq,
- ip->ip_ttl,
- rtt);
- }
- else
- {
- printf("throw away the old package %d\tbyte from %s\t: icmp_seq=%u\tttl=%d\trtt=%.3f\tms",
- len,
- inet_ntoa(m_from.sin_addr),
- icmp->icmp_seq,
- ip->ip_ttl,
- rtt);
- return -1;
- }
- }
转载于:https://www.cnblogs.com/daochong/p/6873543.html
c++ 实现ping相关推荐
- linux下出现ping:unknown host www.baidu.com问题时的解决办法——ubuntu下局域网络的配置...
如果ping域名的时候出现ping:unknown host xxx.xxx 但是ping IP地址的时候可以通的话 可知是dns服务器没有配置好, 查看一下配置文件/etc/resolv.conf ...
- CMD——ping及用其检测网络故障
Ping命令全称Packet Internet Grope,即因特网包探测器.通过调用ICMP(因特网控制报文协议),发送一份ICMP回显请求给目的主机,并等待返回ICMP回显应答.一般用来测试源主机 ...
- RedHat 7.0及CentOS 7.0禁止Ping的三种方法
作者:荒原之梦 原文链接:http://zhaokaifeng.com/?p=538 前言: "Ping"属于ICMP协议(即"Internet控制报文协议") ...
- 【Ubuntu】ping: unknown host www.baidu.com
1.问题描述 每次重新设置网络后,ping百度总是报错: $ ping www.baidu.com ping: unknown host www.baidu.com 2.原因分析 原因是:查看/etc ...
- 10 ping不通widwos7 windwos_弱电老司机总结的10种视频监控系统故障解决方法,学会,事半功倍...
最近有许多的读者咨询关于视频监控系统维修方法的事情,有没有总结一些常见故障的解决方案呢?当然有的,今天分享一些常见故障解决方法. 正文: 视频监控系统通常出现摄像机没有画面.或者画面卡顿.丢失等情况, ...
- centos iptables关于ping
配置iptables策略后,一般来说INPUT都是DROP然后配置需要通过的 当执行: iptables -P INPUT DROP 后,机器就不能被ping通了! 因为icmp没有添加到规则中! 于 ...
- 服务器ping你可以ping通,你ping服务器ping不同的解决方案!!
这几天让公司的服务器弄的蛋疼啊!!三天两头的出问题,主管脸色不大好看,我这里也郁闷的要死.所以发誓一定要把好安全关!! 今天在自己的虚拟机上边装了一个winserver2003标准版,搭建好环境之后发 ...
- 响应因特网端口ping命令_如何使用Ping命令识别基本的Internet问题
响应因特网端口ping命令 Next time you call your help desk, do you want to wow them with your networking knowle ...
- 电脑显示服务器地址无法ping通,网关无法Ping通故障及解决方法
很多网络故障是常见问题,一般的三板斧方法就能解决问题,但有些故障容易让我们多走弯路,我们不妨拓宽故障排查范围,换换思路. 在与网络亲密接触的过程中,我们或多或少地会遇到一些网络故障,对于许多网络故障来 ...
- 海思涵科技WIFI认证服务器不在线,在海思平台外加一个usb wifi模块,mt7601 加载ok,配置网络ok,但不能ping通?...
请教下:我用mt7601 usb wifi模块 加载驱动 配置网络后经常打印 PeerBeaconAtJoinAction(): Set CentralChannel=1 PeerBeaconAtJo ...
最新文章
- 教育部回应:没有使用“第一学历”这个概念!
- Android的数据存储
- Java yield详解_Java 中的 yield 关键字
- Chapter 3 Phenomenon——19
- 比亚迪定薪后多久给offer_比亚迪车主给爱车做四门隔音,没想到两年后肠子都悔青...
- Qt编程'hello world
- 怎么看铜皮属性_阻抗匹配怎么做 及阻抗匹配的作用。
- java实现小说采集_Java实现一个小说采集程序的简单实例
- 3D次时代来临 如何玩转红蓝立体游戏
- 把unc0ver.ipa重签名后安装到手机上实现越狱
- oppo小布机器人_OPPO小布助手喜迎重大升级,你的私人全能管家现已上线!
- 计算机底层知识之运行环境可执行文件
- 服务器虚拟化用什么显卡,显卡虚拟化使用及配置技术
- Android 4.0.4系统下实现apk的静默安装和启动
- 一篇文章搞懂php文件系统基本操作
- 今日份安利:手机上怎么去图片水印
- git ------ git clone方法总结(可直接加账户和密码)
- 投资基建无异扩大货币供应
- 视频教程-系统集成项目管理工程师考试-技术部分-软考
- 百度AI学习第一天_调用API接口通用步骤
热门文章
- 吴恩达深度学习2.2笔记_Improving Deep Neural Networks_优化算法
- 同一路由带参刷新,以及params和query两种方式传参的异同
- 彻底删除0KB顽固文件或文件夹的方法
- 品《阿里巴巴大数据实践-大数据之路》一书(上)
- 关于头文件,全局变量,extern,static
- java文件格式转换
- Leetcode 1015. Smallest Integer Divisible by K
- SQL基础(八)-- sql左右连接中的on and 和 on where 的区别
- docker 清理容器的一些命令,彻底或选择清理
- webpack打包样式代码去重