VC Ping IP的类

Pingip.cpp
#include “stdafx.h”
#include “ping.h”
void CPing::Ping(UINT nRetries,LPCSTR pstrHost,HWND hWnd)
{
SOCKET	  rawSocket;
LPHOSTENT lpHost;
UINT	  nLoop;
int       nRet;
struct    sockaddr_in saDest;
struct    sockaddr_in saSrc;
DWORD	  dwTimeSent;
DWORD	  dwElapsed;
u_char    cTTL;
m_hWnd = hWnd;
CString str;
//创建一个Raw套接字
rawSocket = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
if (rawSocket == SOCKET_ERROR)
{
CString strMsg;
strMsg.Format(“创建套接字发生错误 – WSAError: %ld”,WSAGetLastError());
//发送报错信息
SendMessage(m_hWnd,WM_MSG_STATUS,0,(LPARAM) AllocBuffer(strMsg));
return;
}
//获得主机信息
lpHost = gethostbyname(pstrHost);
//构造目标套接字地址信息
saDest.sin_addr.s_addr = *((u_long FAR *)(lpHost->h_addr));
saDest.sin_family = AF_INET;
saDest.sin_port = 70;
//ping
for (nLoop = 0; nLoop < nRetries; nLoop++)
{
//发送ICMP回应请求
SendEchoRequest(rawSocket, &saDest);
nRet = WaitForEchoReply(rawSocket);
if (!nRet)
{
str.Format(“Request Timed Out”);
SendMessage(m_hWnd,WM_MSG_STATUS,3,(LPARAM)AllocBuffer(str));
}
else
{
//获得回应
dwTimeSent = RecvEchoReply(rawSocket,&saSrc,&cTTL);
//计算时间
dwElapsed = GetTickCount() – dwTimeSent;
str.Format(“Reply from: %s: bytes=%d time=%ldms TTL=%d”,
inet_ntoa(saSrc.sin_addr),REQ_DATASIZE,dwElapsed,cTTL);
SendMessage(m_hWnd,WM_MSG_STATUS,2,(LPARAM)AllocBuffer(str));
Sleep(1000);
}
}
nRet = closesocket(rawSocket);
if (nRet == SOCKET_ERROR)
{
CString strMsg;
strMsg.Format(“关闭套接字发生错误 – WSAError: %ld”,WSAGetLastError());
//发送报错信息
SendMessage(m_hWnd,WM_MSG_STATUS,0,(LPARAM) AllocBuffer(strMsg));
}
}
//发送ICMPECHO数据包请求
int CPing::SendEchoRequest(SOCKET s,LPSOCKADDR_IN lpstToAddr)
{
static ECHOREQUEST echo;
static nId = 1;
static nSeq = 1;
int nRet;
//构造回应请求
echo.icmpHdr.Type = 8;
echo.icmpHdr.Code = 0;
echo.icmpHdr.Checksum = 0;
echo.icmpHdr.ID = nId++;
echo.icmpHdr.Seq = nSeq++;
for(nRet=0;nRet<REQ_DATASIZE;nRet++)
echo.cData[nRet] = ‘ ‘+nRet;
//保存发送时间
echo.dwTime = GetTickCount();
echo.icmpHdr.Checksum = in_cksum((u_short *)&echo,sizeof(ECHOREQUEST));
//发送请求
nRet = sendto(s,(LPSTR)&echo,sizeof(ECHOREQUEST),0,
(LPSOCKADDR)lpstToAddr,sizeof(SOCKADDR_IN));
if (nRet == SOCKET_ERROR)
{
CString strMsg;
strMsg.Format(“发送数据时发生错误 – WSAError: %ld”,WSAGetLastError());
//发送报错信息
SendMessage(m_hWnd,WM_MSG_STATUS,0,(LPARAM) AllocBuffer(strMsg));
}
return (nRet);
}
//接收ICMPECHO数据包回应
DWORD CPing::RecvEchoReply(SOCKET s,LPSOCKADDR_IN lpsaFrom,u_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)
{
CString strMsg;
strMsg.Format(“接收数据时发生错误 – WSAError: %ld”,WSAGetLastError());
//发送报错信息
SendMessage(m_hWnd,WM_MSG_STATUS,0,(LPARAM) AllocBuffer(strMsg));
}
//返回发送的时间
*pTTL = echoReply.iphdr.TTL;
return(echoReply.echorequest.dwTime);
}
//等待回应
int CPing::WaitForEchoReply(SOCKET s)
{
struct timeval Time;
fd_set fds;
fds.fd_count = 1;
fds.fd_array[0] = s;
Time.tv_sec = 1;
Time.tv_usec = 0;
return(select(1,&fds,NULL,NULL,&Time));
}
//转换地址
u_short CPing::in_cksum(u_short *addr,int len)
{
register int nleft = len;
register u_short *n = addr;
register u_short answer;
register int sum = 0;
while(nleft > 1)
{
sum += *n++;
nleft -= 2;
}
if(nleft == 1)
{
u_short	u = 0;
*(u_char *)(&u) = *(u_char *)n;
sum += u;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
answer = ~sum;
return (answer);
}
char* CPing::AllocBuffer(CString strMsg)
{
int nLen = strMsg.GetLength();
char *pBuffer = new char[nLen+1];
strcpy(pBuffer,(const char*)strMsg);
ASSERT(pBuffer != NULL);
return pBuffer;
}

pingip.h

// Ping.h
//
#define REQ_DATASIZE 32	//Echo请求数据的大小
class CPing
{
public:
static char* AllocBuffer(CString strMsg);
HWND m_hWnd; //窗口句柄
void Ping(UINT nRetries,LPCSTR pstrHost,HWND hWnd);
int WaitForEchoReply(SOCKET s);
//ICMP回应的请求和回答函数
int	SendEchoRequest(SOCKET, LPSOCKADDR_IN);
DWORD RecvEchoReply(SOCKET, LPSOCKADDR_IN,u_char *pTTL);
u_short in_cksum(u_short *addr, int len);
protected:
};
typedef struct IP_HDR
{
u_char  VIHL;	   //Version and IHL
u_char	TOS;	   //Type Of Service
short	TotLen;	   //总长度
short	ID;	   //标识
short	FlagOff;	   //标记
u_char	TTL;	   //生命期
u_char	Protocol;	   //协议
u_short	Checksum;	   //检查和
struct	in_addr iaSrc; //源地址
struct	in_addr iaDst; //目的地址
}IPHDR, *PIPHDR;
typedef struct IC_MPHDR
{
u_char	Type;	  //类型
u_char	Code;	  //编码
u_short	Checksum; //检查和
u_short	ID;	  //标识
u_short	Seq;	  //顺序
char	Data;	  //数据
}ICMPHDR, *PICMPHDR;
typedef struct ICMPECHOREQUEST
{
ICMPHDR icmpHdr;
DWORD	dwTime;
char	cData[REQ_DATASIZE];
}ECHOREQUEST, *PECHOREQUEST;
typedef struct ICMPECHOREPLY
{
IPHDR	iphdr;
ECHOREQUEST	echorequest;
char    cFiller[256];
}ECHOREPLY, *PECHOREPLY;

转载于:https://www.cnblogs.com/rogee/archive/2011/05/24/2055892.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值