实现ping功能

头文件

#pragma once

#include <Winsock2.h>
#include <IPHlpApi.h>

#pragma comment(lib, "Iphlpapi.lib")
#pragma comment(lib, "Ws2_32.lib")

typedef HANDLE(WINAPI* ICMPCREATEFILE)(VOID);
typedef INT(WINAPI* ICMPCLOSEHANDLE)(HANDLE);
typedef DWORD(WINAPI* ICMPSENDECHO)(HANDLE, DWORD, LPVOID, WORD, PIP_OPTION_INFORMATION, LPVOID, DWORD, DWORD);

class CICMPPing
{
public:
	CICMPPing(void);
	~CICMPPing(void);

	BOOL InitializeICMP();
	BOOL Ping(const char* host);
	VOID ReleaseICMP();

private:
	HINSTANCE m_hDLL;
	ICMPCREATEFILE m_pIcmpCreateFile;
	ICMPCLOSEHANDLE m_pIcmpCloseHandle;
	ICMPSENDECHO m_pIcmpSendEcho;
};

CPP文件

#include "StdAfx.h"
#include "ICMPPing.h"

CICMPPing::CICMPPing(void)
{
	m_hDLL = NULL;
	m_pIcmpSendEcho = NULL;
	m_pIcmpCreateFile = NULL;
	m_pIcmpCloseHandle = NULL;
}

CICMPPing::~CICMPPing(void)
{
	ReleaseICMP();
}

BOOL CICMPPing::InitializeICMP()
{
	m_hDLL = ::LoadLibrary(_T("ICMP.DLL"));
	if (NULL != m_hDLL)
	{
		m_pIcmpCreateFile = (ICMPCREATEFILE)GetProcAddress(m_hDLL, "IcmpCreateFile");
		m_pIcmpCloseHandle = (ICMPCLOSEHANDLE)GetProcAddress(m_hDLL, "IcmpCloseHandle");
		m_pIcmpSendEcho = (ICMPSENDECHO)GetProcAddress(m_hDLL, "IcmpSendEcho");
		if ((m_pIcmpCreateFile == NULL) || (m_pIcmpCloseHandle == NULL) || (m_pIcmpSendEcho == NULL))
			return FALSE;

		return TRUE;
	}
	return FALSE;
}

BOOL CICMPPing::Ping(const char* host)
{
	DWORD timeOut = 500;                                              //设置超时   
	ULONG hAddr = inet_addr(host);                                     //如果是IP地址就直接转换   
	if (hAddr == INADDR_NONE)
	{
		hostent* hp = gethostbyname(host);                             //如果是域名就用DNS解析出IP地址   
		if (hp)
			memcpy(&hAddr, hp->h_addr_list, hp->h_length);             //IP地址   
		else
		{
			return FALSE;
		}
	}

	HANDLE hIp = m_pIcmpCreateFile();
	IP_OPTION_INFORMATION ipoi;
	memset(&ipoi, 0, sizeof(IP_OPTION_INFORMATION));
	ipoi.Ttl = 128;														//Time-To-Live   

	unsigned char pSend[36] = {0};                                      //发送包   
	memset(pSend, 'E', 32);

	int repSize = sizeof(ICMP_ECHO_REPLY) + 32;
	unsigned char pReply[100];                                          //接收包   
	ICMP_ECHO_REPLY* pEchoReply = (ICMP_ECHO_REPLY*)pReply;

	DWORD nPackets = m_pIcmpSendEcho(hIp, hAddr, pSend, 32, &ipoi, pReply, repSize, timeOut);             //发送ICMP数据报文   

	if (pEchoReply->Status != 0)                                                                  //超时,可能是主机禁用了ICMP 或者目标主机不存在  
	{
		m_pIcmpCloseHandle(hIp);
		return FALSE;
	}

	m_pIcmpCloseHandle(hIp);
	return TRUE;
}

VOID CICMPPing::ReleaseICMP()
{
	if (NULL != m_hDLL)
	{
		::FreeLibrary(m_hDLL);

		m_pIcmpCloseHandle = NULL;
		m_pIcmpCreateFile = NULL;
		m_pIcmpSendEcho = NULL;
	}
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值