明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

使用TCP堆棧來(lái)Ping計(jì)算機(jī)

[摘要]//原著:Les Jordan//譯者:重慶大學(xué)光電工程學(xué)院 賈旭濱//歡迎大家批評(píng)指教,謝謝! 以下的這個(gè)類是解決一個(gè)很普通的問(wèn)題的:在一臺(tái)WIN95的計(jì)算機(jī)上怎么樣利用MSTCP堆棧去PING另外一臺(tái)計(jì)算機(jī)。當(dāng)然,這個(gè)類在NT3.51和NT4上也可以用。顯然,MicroSoft公司不...
//原著:Les Jordan
//譯者:重慶大學(xué)光電工程學(xué)院   賈旭濱
//歡迎大家批評(píng)指教,謝謝!

    以下的這個(gè)類是解決一個(gè)很普通的問(wèn)題的:在一臺(tái)WIN95的計(jì)算機(jī)上怎么樣利用MSTCP堆棧去PING另外一臺(tái)計(jì)算機(jī)。當(dāng)然,這個(gè)類在NT3.51和NT4上也可以用。顯然,MicroSoft公司不會(huì)那么笨,在WIN系統(tǒng)中又另外構(gòu)造這么一個(gè)單獨(dú)的機(jī)制來(lái)解決這個(gè)問(wèn)題,讓本來(lái)就復(fù)雜的WIN系統(tǒng)更加復(fù)雜。那么,我們只能用ICMP DLL自己來(lái)解決這個(gè)問(wèn)題了。不過(guò),很讓人失望,MicroSoft公司直到Winsock 2.0也沒(méi)有解決這個(gè)問(wèn)題。

    難題就是:給一個(gè)計(jì)算機(jī)的名字,或者一臺(tái)計(jì)算機(jī)的IP地址,怎么樣去PING它,而且得到它的響應(yīng)時(shí)間。所以我們用了ICMP DLL,而對(duì)于一些SOCKET結(jié)構(gòu)來(lái)說(shuō),在CSocket中已經(jīng)全部都有定義了。所以,下面的類是一個(gè)CSocket的子類,它將會(huì)有更好的功能來(lái)解決更多的問(wèn)題。不過(guò)你得先得到ICMPAPI.H,ICMAPI.CPP,ICMP.LIB和IPEXPORT.H,IPEXPORT.CPP這些文件,這些文件應(yīng)該加在你的工程中。這些文件你可以在Microsoft Developers Network的光盤上得到,不過(guò)在微軟公司的主頁(yè)上也能拿到,而且更新。

類中有4個(gè)公共函數(shù),如下:
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)函數(shù)使用一個(gè)IP地址的字符串來(lái)作為參數(shù),返回值是IP地址值。
    ResolveName(CString strHostName)函數(shù)使用一計(jì)算機(jī)名的字符串來(lái)作為參數(shù),經(jīng)過(guò)DNS或者WINS的解析,返回值是被PING計(jì)算機(jī)的IP 地址,注意它使用了GetHostByName模塊化。

    GetIP(unsigned long ulIP)函數(shù)是以IP地址作為參數(shù)(注意是IP地址),返回值是一個(gè)表示IP地址的字符串。

    PingHost(unsigned long ulIP, int iPingTimeout)函數(shù),第1個(gè)參數(shù)是IP地址(注意是IP地址,而不是IP地址的字符串),第2個(gè)參數(shù)是表示時(shí)間值的,表示間隔時(shí)間的。函數(shù)功能是,去PING一臺(tái)計(jì)算機(jī),返回值是PING的響應(yīng)時(shí)間。

以下是代碼:

//*
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
//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;

}