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;

你可能感兴趣的:(ping)