//原著:Les Jordan //譯者:重慶大學光電工程學院 賈旭濱 //歡迎大家批評指教,謝謝!
以下的這個類是解決一個很普通的問題的:在一臺WIN95的計算機上怎么樣利用MSTCP堆棧去PING另外一臺計算機。當然,這個類在NT3.51和NT4上也可以用。顯然,MicroSoft公司不會那么笨,在WIN系統中又另外構造這么一個單獨的機制來解決這個問題,讓本來就復雜的WIN系統更加復雜。那么,我們只能用ICMP DLL自己來解決這個問題了。不過,很讓人失望,MicroSoft公司直到Winsock 2.0也沒有解決這個問題。
難題就是:給一個計算機的名字,或者一臺計算機的IP地址,怎么樣去PING它,而且得到它的響應時間。所以我們用了ICMP DLL,而對于一些SOCKET結構來說,在CSocket中已經全部都有定義了。所以,下面的類是一個CSocket的子類,它將會有更好的功能來解決更多的問題。不過你得先得到ICMPAPI.H,ICMAPI.CPP,ICMP.LIB和IPEXPORT.H,IPEXPORT.CPP這些文件,這些文件應該加在你的工程中。這些文件你可以在Microsoft Developers Network的光盤上得到,不過在微軟公司的主頁上也能拿到,而且更新。
類中有4個公共函數,如下: unsigned long ResolveIP(CString strIP) unsigned long ResolveName(CString strHostName) CString GetIP(unsigned long ulIP) DWORD PingHost(unsigned long ulIP, int iPingTimeout)
ResolveIP(CString strIP)函數使用一個IP地址的字符串來作為參數,返回值是IP地址值。 ResolveName(CString strHostName)函數使用一計算機名的字符串來作為參數,經過DNS或者WINS的解析,返回值是被PING計算機的IP 地址,注意它使用了GetHostByName模塊化。
GetIP(unsigned long ulIP)函數是以IP地址作為參數(注意是IP地址),返回值是一個表示IP地址的字符串。
PingHost(unsigned long ulIP, int iPingTimeout)函數,第1個參數是IP地址(注意是IP地址,而不是IP地址的字符串),第2個參數是表示時間值的,表示間隔時間的。函數功能是,去PING一臺計算機,返回值是PING的響應時間。
以下是代碼:
//* //------------------------------------------------------------------------- //------------------------------------------------------------------------- //icmpecho.h //------------------------------------------------------------------------- //------------------------------------------------------------------------ //* class CIcmpEcho : public CSocket { // Attributes public:
// Operations public: CIcmpEcho(); virtual ~CIcmpEcho();
unsigned long ResolveIP(CString strIP); unsigned long ResolveName(CString strHostName);
DWORD PingHost(unsigned long ulIP, int iPingTimeout);
CString GetIP(unsigned long ulIP);
// Overrides public: // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CIcmpEcho) //}}AFX_VIRTUAL
// Generated message map functions //{{AFX_MSG(CIcmpEcho) // NOTE - the ClassWizard will add and remove member functions here. //}}AFX_MSG
// Implementation protected: }; ///////////////////////////////////////////////////////////////////////////// //* //------------------------------------------------------------------------------------------------------------------ //icmpecho.cpp //------------------------------------------------------------------------------------------------------------------ //* // IcmpEcho.cpp : implementation file //
#include "IcmpEcho.h"
extern "C" { #include "ipexport.h" #include "icmpapi.h" }
#define PING_TIMEOUT 100
#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif
///////////////////////////////////////////////////////////////////////////// // CIcmpEcho
CIcmpEcho::CIcmpEcho() { }
CIcmpEcho::~CIcmpEcho() { }
// Do not edit the following lines, which are needed by ClassWizard. #if 0 BEGIN_MESSAGE_MAP(CIcmpEcho, CSocket) //{{AFX_MSG_MAP(CIcmpEcho) //}}AFX_MSG_MAP END_MESSAGE_MAP() #endif // 0
///////////////////////////////////////////////////////////////////////////// // CIcmpEcho member functions unsigned long CIcmpEcho::ResolveIP(CString strIP) { //Task 1: Given IP Address i.e. "111.111.111.111", // Return Network byte ordered address (ulIP)
unsigned long ulIP;
ulIP =(IPAddr)inet_addr(strIP);
return ulIP; }
unsigned long CIcmpEcho::ResolveName(CString strHostName) { //Task 1: Resolve HostName (through DNS or WINS, whichever appropriate) //Task 2: Return network byte ordered address (ulIP)
unsigned long ulIP; hostent* phostent;
phostent = gethostbyname(strHostName); if (phostent == NULL) return 0;
ulIP = *(DWORD*)(*phostent->h_addr_list);
return ulIP;
}
DWORD CIcmpEcho::PingHost(unsigned long ulIP, int iPingTimeout) { //Task 1: Open ICMP Handle //Task 2: Create Structure to receive ping reply //Task 3: SendPing (SendEcho) //Task 4: Close ICMP Handle //Task 5: Return RoundTripTime
unsigned long ip = ulIP;
HANDLE icmphandle = IcmpCreateFile();
char reply[sizeof(icmp_echo_reply)+8];
icmp_echo_reply* iep=(icmp_echo_reply*)&reply; iep->RoundTripTime = 0xffffffff;
IcmpSendEcho(icmphandle,ip,0,0,NULL,reply,sizeof(icmp_echo_reply)+8,iPingTimeout);
IcmpCloseHandle(icmphandle);
return iep->RoundTripTime;
}
CString CIcmpEcho::GetIP(unsigned long ulIP) { //Task 1: Given a host order ulIP Address // Return a IP address in format of xxx.xxx.xxx.xxx
LPSTR szAddr;
struct in_addr inetAddr; inetAddr.s_addr = (IPAddr)ulIP;
szAddr = inet_ntoa(inetAddr);
CString csIP = szAddr;
return csIP;
}
|