现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

如何在vc中实现ping功能

2014-01-01 21:42 工业·编程 ⁄ 共 6309字 ⁄ 字号 暂无评论

因为想实现这个功能,所以在网上找了下资料,从中截取出来这个类,可以很方便的放在自己的程序中使用。

相关阅读

----Ping程序C++实现

//
// Ping.h
//

#pragma pack(1)

#define ICMP_ECHOREPLY    0
#define ICMP_ECHOREQ    8

class CPing
{
public:
    HWND m_hWnd;
    BOOL Ping(UINT nRetries,LPCSTR pstrHost,HWND hWnd);
    int  WaitForEchoReply(SOCKET s);
    // ICMP Echo Request/Reply functions
    int        SendEchoRequest(SOCKET, LPSOCKADDR_IN);
    DWORD    RecvEchoReply(SOCKET, LPSOCKADDR_IN, u_char *);
    u_short in_cksum(u_short *addr, int len);

protected:
    void WSAError(LPCSTR pstrFrom);

};

 

// IP Header -- RFC 791
typedef struct tagIPHDR
{
    u_char  VIHL;            // Version and IHL
    u_char    TOS;            // Type Of Service
    short    TotLen;            // Total Length
    short    ID;                // Identification
    short    FlagOff;        // Flags and Fragment Offset
    u_char    TTL;            // Time To Live
    u_char    Protocol;        // Protocol
    u_short    Checksum;        // Checksum
    struct    in_addr iaSrc;    // Internet Address - Source
    struct    in_addr iaDst;    // Internet Address - Destination
}IPHDR, *PIPHDR;

// ICMP Header - RFC 792
typedef struct tagICMPHDR
{
    u_char    Type;            // Type
    u_char    Code;            // Code
    u_short    Checksum;        // Checksum
    u_short    ID;                // Identification
    u_short    Seq;            // Sequence
    char    Data;            // Data
}ICMPHDR, *PICMPHDR;

#define REQ_DATASIZE 32        // Echo Request Data size

// ICMP Echo Request
typedef struct tagECHOREQUEST
{
    ICMPHDR icmpHdr;
    DWORD    dwTime;
    char    cData[REQ_DATASIZE];
}ECHOREQUEST, *PECHOREQUEST;

// ICMP Echo Reply
typedef struct tagECHOREPLY
{
    IPHDR    ipHdr;
    ECHOREQUEST    echoRequest;
    char    cFiller[256];
}ECHOREPLY, *PECHOREPLY;

#pragma pack()

//
// THIS CODE IS BASED ON THE CODE FROM
// THE BOOK WINSOCK 2.0 BY LEWIS NAPPER...
//
//

CPP文件

#include "stdafx.h"
#include "ping.h"

BOOL 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;

    ASSERT(IsWindow(hWnd));
    // Create a Raw socket
    rawSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
    if (rawSocket == SOCKET_ERROR)
    {
        return FALSE;
    }
   
    // Lookup host
    lpHost = gethostbyname(pstrHost);
    if (lpHost == NULL)
    {
        //str.Format("Host not found: %s", pstrHost);
        return FALSE;
    }
   
    // Setup destination socket address
    saDest.sin_addr.s_addr = *((u_long FAR *) (lpHost->h_addr));
    saDest.sin_family = AF_INET;
    saDest.sin_port = 0;
    // Tell the user what we're doing
    str.Format("Pinging %s [%s] with %d bytes of data:",pstrHost,inet_ntoa(saDest.sin_addr),REQ_DATASIZE);
    // Ping multiple times
    for (nLoop = 0; nLoop < nRetries; nLoop++)
    {
        // Send ICMP echo request
        SendEchoRequest(rawSocket, &saDest);
        Sleep(1000);
        nRet = WaitForEchoReply(rawSocket);
        if (nRet == SOCKET_ERROR)
        {
            //WSAError("select()");
            return FALSE;
        }
        if (!nRet)
        {
            //str.Format("Request Timed Out");
            return FALSE;
        }
        else
        {
            return TRUE;
        }
    }
    nRet = closesocket(rawSocket);
}

int CPing::SendEchoRequest(SOCKET s,LPSOCKADDR_IN lpstToAddr)
{
    static ECHOREQUEST echoReq;
    static nId = 1;
    static nSeq = 1;
    int nRet;

    // Fill in echo request
    echoReq.icmpHdr.Type        = ICMP_ECHOREQ;
    echoReq.icmpHdr.Code        = 0;
    echoReq.icmpHdr.Checksum    = 0;
    echoReq.icmpHdr.ID            = nId++;
    echoReq.icmpHdr.Seq            = nSeq++;

    // Fill in some data to send
    for (nRet = 0; nRet < REQ_DATASIZE; nRet++)
        echoReq.cData[nRet] = ' '+nRet;

    // Save tick count when sent
    echoReq.dwTime                = GetTickCount();

    // Put data in packet and compute checksum
    echoReq.icmpHdr.Checksum = in_cksum((u_short *)&echoReq, sizeof(ECHOREQUEST));

    // Send the echo request                                   
    nRet = sendto(s,                        /* socket */
                 (LPSTR)&echoReq,            /* buffer */
                 sizeof(ECHOREQUEST),
                 0,                            /* flags */
                 (LPSOCKADDR)lpstToAddr, /* destination */
                 sizeof(SOCKADDR_IN));   /* address length */

    if (nRet == SOCKET_ERROR)
        WSAError("sendto()");
    return (nRet);
}

DWORD CPing::RecvEchoReply(SOCKET s, LPSOCKADDR_IN lpsaFrom, u_char *pTTL)
{
    ECHOREPLY echoReply;
    int nRet;
    int nAddrLen = sizeof(struct sockaddr_in);

    // Receive the echo reply   
    nRet = recvfrom(s,                    // socket
                    (LPSTR)&echoReply,    // buffer
                    sizeof(ECHOREPLY),    // size of buffer
                    0,                    // flags
                    (LPSOCKADDR)lpsaFrom,    // From address
                    &nAddrLen);            // pointer to address len

    // Check return value
    if (nRet == SOCKET_ERROR)
        WSAError("recvfrom()");

    // return time sent and IP TTL
    *pTTL = echoReply.ipHdr.TTL;

    return(echoReply.echoRequest.dwTime);          
}

int CPing::WaitForEchoReply(SOCKET s)
{
    struct timeval Timeout;
    fd_set readfds;

    readfds.fd_count = 1;
    readfds.fd_array[0] = s;
    Timeout.tv_sec = 1;
    Timeout.tv_usec = 0;

    return(select(1, &readfds, NULL, NULL, &Timeout));
}

void CPing::WSAError(LPCSTR lpMsg)
{
    CString strMsg;
    strMsg.Format("%s - WSAError: %ld",lpMsg,WSAGetLastError());   
//    ::PostMessage(m_hWnd,WM_MSG_STATUS, 0, (LPARAM) AllocBuffer(strMsg));
}

 

//
// Mike Muuss' in_cksum() function
// and his comments from the original
// ping program
//
// * Author -
// *    Mike Muuss
// *    U. S. Army Ballistic Research Laboratory
// *    December, 1983

/*
*            I N _ C K S U M
*
* Checksum routine for Internet Protocol family headers (C Version)
*
*/
u_short CPing::in_cksum(u_short *addr, int len)
{
    register int nleft = len;
    register u_short *w = addr;
    register u_short answer;
    register int sum = 0;

    /*
     *  Our algorithm is simple, using a 32 bit accumulator (sum),
     *  we add sequential 16 bit words to it, and at the end, fold
     *  back all the carry bits from the top 16 bits into the lower
     *  16 bits.
     */
    while( nleft > 1 )  {
        sum += *w++;
        nleft -= 2;
    }

    /* mop up an odd byte, if necessary */
    if( nleft == 1 ) {
        u_short    u = 0;

        *(u_char *)(&u) = *(u_char *)w ;
        sum += u;
    }

    /*
     * add back carry outs from top 16 bits to low 16 bits
     */
    sum = (sum >> 16) + (sum & 0xffff);    /* add hi 16 to low 16 */
    sum += (sum >> 16);            /* add carry */
    answer = ~sum;                /* truncate to 16 bits */
    return (answer);
}

  1. 这个时候可以加个定时器,定时的查看网络是可以ping通: 
  2. m_strRemoteMachine.Format("%s","192.168.1.178"); 
  3. CPing myPing; 
  4. bool blPing=myPing.Ping(5,m_strRemoteMachine,this->m_hWnd); 

记得在加入<afxsock.h>哦。。。

给我留言

留言无头像?