发布一个C编写的Ping类

CPing.h

// Ping.h: interface for the CPing class.
//
//

#if !defined(AFX_PING_H__2EBF2C11_A0A3_403B_9EB2_1905CFF8EE58__INCLUDED_)
#define AFX_PING_H__2EBF2C11_A0A3_403B_9EB2_1905CFF8EE58__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include<Winsock.h>
#include<stdlib.h>
#include<stdio.h>
#pragma comment(lib,"ws2_32.lib")

#define ICMP_ECHOREPLY 0
#define ICMP_ECHOREQ 8
//
typedef struct tagIPDR
{
	u_char VIHL;//版本和类型
	u_char TOS;//服务质量
	u_char shortTotLen;//长度
    u_char shortID;//编号
	u_char shortFlagOff;//分片,Fragment
	u_char TTL;//生存时间
	u_char Protocol;//协议类型
	u_short Checksum;//校验和
	struct in_addr iaSrc;//源地址
	struct in_addr isDet;//目的地址
}IPHDR,*PIPHDR;//RFC791 的IP协议头类型


typedef struct tagICMP
{
	u_char Type;//类型
	u_char Code;//代号
	u_short  Checksum;//校验号
	u_short ID;//标识号
	u_short Seq;//列号
	char Data;//数据信息
}ICMPHDR,*PICMPHDR;//RFC 792 ICMP协议头

/
#define REQ_DATASIZE 32
typedef struct tagECHOREQUEST
{
	ICMPHDR icmpHdr;//ICMP协议头
	DWORD dwTime;//数据传输时间
	char cData[REQ_DATASIZE];//传输数据
}ECHOREQUEST,*PECHOREQUEST;//请求回传的数据长度

///
typedef struct tagECHOREPLY
{
	IPHDR ipHdr;
	ECHOREQUEST echoRequest;
	char cFiler[256];
}ECHOREPLY,*PECHOREPLY;//回送请求报文

// 用于Ping的探测技术
class CPing  
{
public:
	CPing();
	virtual ~CPing();
private:
	void InitPing();
	void CleanUP();
	void ReportError(LPCSTR psrtFrom);
	int WaitForEchoReply(SOCKET s);
	int SendEchoRequest(SOCKET,LPSOCKADDR_IN);
	DWORD RecvEchoReply(SOCKET,LPSOCKADDR_IN,char*);
	u_short in_cksum(u_short *addr,int len);
public:
	bool Ping(CString strIP);
	CString LongIPToStr(long nIP);
	long  StrIPToLong(CString strIP);
private:
	DWORD time;
};


#endif // !defined(AFX_PING_H__2EBF2C11_A0A3_403B_9EB2_1905CFF8EE58__INCLUDED_)


CPing.cpp

// Ping.cpp: implementation of the CPing class.
//
//

#include "stdafx.h"

#include "Ping.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//
// Construction/Destruction
//

CPing::CPing()
{
	InitPing();
}

CPing::~CPing()
{
	CleanUP();
}
void CPing::InitPing()
{
	WSADATA wsaData;
	WORD version=MAKEWORD(1,1);
	if(WSAStartup(version,&wsaData))
	{
		printf("初始化协议栈错误\n");
		return ;
	}
	if(wsaData.wVersion!=version)
	{
        printf("不支持WIDOWS的套接字\n");
		return ;
	}
}
void CPing::CleanUP()
{
	WSACleanup();
}
// 打印错误的代码
void CPing::ReportError(LPCSTR psrtFrom)
{
	printf("%s发生错误,错误号:%d\n",psrtFrom,WSAGetLastError());
}
// 等待回应信息
int CPing::WaitForEchoReply(SOCKET s)
{
 struct timeval Timeout;
 fd_set readfds;
 readfds.fd_count=1;
 readfds.fd_array[0]=s;
 Timeout.tv_sec=5;
 Timeout.tv_usec=0;
 return select(1,&readfds,NULL,NULL,&Timeout);
}
//发送请求信息
int CPing::SendEchoRequest(SOCKET s,LPSOCKADDR_IN lpstToAddr)
{
	static ECHOREQUEST echoReq;
	static nId=1;
	static nSeq=1;
	static nRet;
	echoReq.icmpHdr.Type=ICMP_ECHOREQ;
    echoReq.icmpHdr.Code=0;
	echoReq.icmpHdr.Checksum=0;
	echoReq.icmpHdr.ID=nId++;
	echoReq.icmpHdr.Seq=nSeq++;
	for(nRet=0;nRet<REQ_DATASIZE;nRet++)
	  echoReq.cData[nRet]=nRet;
    echoReq.dwTime=GetTickCount();
	time=echoReq.dwTime;//记录发送时间 
	echoReq.icmpHdr.Checksum=in_cksum((u_short *)&echoReq,sizeof(ECHOREQUEST));
	nRet=sendto(s,(LPCSTR)&echoReq,sizeof(ECHOREQUEST),0,(LPSOCKADDR)lpstToAddr,sizeof(SOCKADDR_IN));
	if(nRet==SOCKET_ERROR)
	 ReportError("发送出错");
    return nRet;
}
// 接收回应的信息
DWORD CPing::RecvEchoReply(SOCKET s,LPSOCKADDR_IN lpsaFrom,char *pTTL)
{
	ECHOREPLY echoReply;
	int nRet;
	int nAddrLen=sizeof(struct sockaddr_in);
    nRet=recvfrom(s,(LPSTR)&echoReply,sizeof(ECHOREPLY),0,(LPSOCKADDR)lpsaFrom,&nAddrLen);
	if(nRet==SOCKET_ERROR)
		ReportError("接收");
	*pTTL=echoReply.ipHdr.TTL;
	return echoReply.echoRequest.dwTime;
}
// 检验和
u_short CPing::in_cksum(u_short *addr,int len)
{
	register int nleft=len;
    register u_short *w=addr;
	register u_short answer;
	register int sum=0;
	while(nleft>1)
	{
		sum+=*w++;
		nleft-=2;
	}
	if(nleft==1)
	{
		u_short u=0;
		*(u_char *)(&u)=*(u_char *)w;
		sum+=u;
	}
	sum=(sum>>16)+(sum&0xffff);
	sum+=(sum>>16);
	answer=~sum;
	return answer;
}
// 探测某IP地址
bool CPing::Ping(CString strIP)
{
	SOCKET rawSocket;
	LPHOSTENT  lpHost;
	struct sockaddr_in saDest;
	struct sockaddr_in saSrc;
	DWORD dwTimeSent;
	DWORD dwElapsed;
	u_char cTTL;
	int nLoop;
	int nRet;
	rawSocket=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
	if(rawSocket==SOCKET_ERROR)
	{
		//ReportError("套接字");
		return false;
	}
	lpHost=gethostbyname(strIP);
   if(lpHost==NULL)
	{
	//	printf("无法找到这主机[%s]\n",strIP);
		return false;
	}
	saDest.sin_addr.s_addr=*((u_long FAR*)(lpHost->h_addr));
	saDest.sin_family=AF_INET;
	saDest.sin_port=0;
	//printf("\n探测主机%s[%s]:%d字节\n",strIP,inet_ntoa(saDest.sin_addr),REQ_DATASIZE);
	int nCount = 0;
	for(nLoop=0;nLoop<4;nLoop++)
	{
		SendEchoRequest(rawSocket,&saDest);
		nRet=WaitForEchoReply(rawSocket);
		if(nRet==SOCKET_ERROR)
		{
		//	ReportError("选择");
			break;
		}
	   	if(!nRet)
		{
		//printf("发送超时\n");	
			break;
		}
		dwTimeSent=RecvEchoReply(rawSocket,&saSrc,(char*)&cTTL);
		dwElapsed=time-dwTimeSent;
		nCount ++;
	    //printf("来自主机[%s]响应,字节:%d 时间:%ld毫秒 最大生存期:%d\n",inet_ntoa(saSrc.sin_addr),REQ_DATASIZE,dwElapsed,cTTL);
	}
    closesocket(rawSocket);
	
	if(nCount > 2)
		return true;

	return false;
}
// 将长整性的IP地址,转换成字符串型 
CString CPing::LongIPToStr(long nIP)
{
	struct   in_addr   addr;   
	addr.s_addr   =   htonl(nIP);   
	CString strIP;
	strIP.Format("%s",inet_ntoa(addr));
	return strIP;
}
// 将字符串型的IP地址,转换成长整性
long  CPing::StrIPToLong(CString strIP)
{
	return ntohl(inet_addr(strIP)); 
}

调用代码:

CPing ping;
bool flag = false;
flag = ping.Ping("172.0.0.1");



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值