如题。

解决方案 »

  1.   

    这实在太多了,随便一搜就很多
    http://www.pconline.com.cn/pcedu/empolder/gj/vc/10207/78851.html
      

  2.   

    #include "stdafx.h"
    #include "windows.h"
    #include "Winsock2.h"
    #pragma comment(lib,"ws2_32.lib")
    #pragma pack(1)
    //
    // ICMP timestamp request and reply 
    //
    typedef struct _ihdr {
      BYTE i_type;
      BYTE i_code; /* type sub code */
      USHORT i_cksum;
      USHORT i_id;
      USHORT i_seq;
      /* This is not the std header, but we reserve space for time */
      ULONG originate_timestamp;
      ULONG receive_timestamp;
      ULONG transmit_timestamp;
    }IcmpHeader;
    void printIcmpHeader(IcmpHeader& timestampreply)
    {
    printf("IcmpHeader type: %d i_code %d i_cksum %d i_id %d i_seq %d \n",timestampreply.i_type, timestampreply.i_code,
    timestampreply.i_cksum, timestampreply.i_id, timestampreply.i_seq);
    printf(" originate_timestamp :%d receive_timestamp %d transmit_timestamp %d \n", timestampreply.originate_timestamp,
    timestampreply.receive_timestamp, timestampreply.transmit_timestamp);
    printf(" pid: %d  \n",GetCurrentProcessId());}
    USHORT g_Seq = 0;
    USHORT checksum(USHORT *buffer, int size) 
    {
    unsigned long cksum=0;
    while( size >1 ) 
    {
    cksum += *buffer ++;
    size -= sizeof ( USHORT );
    }
    if(size ) 
    cksum += *(UCHAR*)buffer;
    cksum = (cksum >> 16) + (cksum & 0xffff);
    cksum += (cksum >>16);
    return (USHORT)(~cksum);
    }
    int _tmain(int argc, _TCHAR* argv[])
    {
    WSADATA wsaData;
    if ( WSAStartup ( MAKEWORD ( 2 , 0 ) , &wsaData ) != 0 )
    return FALSE;
    int iResult , iTimeOut;
    SOCKET m_socketPing = WSASocket (AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0,0);
    if (m_socketPing == INVALID_SOCKET)
    return FALSE;
    iTimeOut = 10000; 
    //Set timeout value for data receive
    iResult = setsockopt(
    m_socketPing,
    SOL_SOCKET,
    SO_RCVTIMEO,
    (char*)&iTimeOut,
    sizeof(iTimeOut));
    if( iResult == SOCKET_ERROR ) 
    return FALSE;
    iTimeOut = 10000; 
    //Set timeout value for data send
    iResult = setsockopt(
    m_socketPing,
    SOL_SOCKET,
    SO_SNDTIMEO,
    (char*)&iTimeOut,
    sizeof(iTimeOut));
    if(iResult == SOCKET_ERROR) 
    return FALSE;
    struct sockaddr_in m_adr_Dest,m_adr_From;
    m_adr_Dest.sin_family = AF_INET;
    m_adr_Dest.sin_addr.s_addr = inet_addr( LPCTSTR ( "127.0.0.3" ) );//216.239.33.99
    IcmpHeader icmph;
    int try_count=0;
    while(try_count<10)
    {
    try_count++;
    int iDataSize = sizeof(IcmpHeader);
    IcmpHeader *icmp_hdr=&icmph;
    ZeroMemory(icmp_hdr,iDataSize);
    icmp_hdr->i_type = 13;//timestamp request
    icmp_hdr->i_code = 0;
    icmp_hdr->i_id = (USHORT)GetCurrentProcessId();
    icmp_hdr->i_cksum = 0;
    icmp_hdr->i_seq = g_Seq++;
    icmp_hdr->originate_timestamp = (GetTickCount());
    icmp_hdr->i_cksum = checksum( ( USHORT* )icmp_hdr, iDataSize );
    printf("sequence %d , originate time %d\n", icmp_hdr->i_seq, icmp_hdr->originate_timestamp);
    int iDataWrite = sendto(
    m_socketPing,
    (char*)icmp_hdr,
    iDataSize,
    0,
    (struct sockaddr*)&m_adr_Dest,
    sizeof(struct sockaddr));
    if (iDataWrite == SOCKET_ERROR)
    {
    if (WSAGetLastError() == WSAETIMEDOUT) 
    {
    continue;
    }
    //terminate the ping if unable to send request.
    return 1;
    }
    //receive the reply
    //(note it.: we sent only the ICMP header and data buffer)
    //IP-Header will be added in before the ICMP header.
    //We could receive more bytes(sizeof IP-Header) than the bytes sent.
    IcmpHeader timestampreply;
    int iFromLen;
    iFromLen = sizeof ( struct sockaddr );
    memset( &m_adr_From ,0 , sizeof( m_adr_From ) );
    //IcmpHeader* pReceiveBuffer = &timestampreply;
    int nReceiveBufferSize = sizeof(IcmpHeader)+1576;
    char* pReceiveBuffer=new char[nReceiveBufferSize];
    int iDataGet = recvfrom(
    m_socketPing,
    (char*)pReceiveBuffer,
    nReceiveBufferSize,
    0,
    (struct sockaddr*)&m_adr_From,
    &iFromLen);

    if (iDataGet == SOCKET_ERROR)
    {
    DWORD iError = WSAGetLastError();
    //if timeout occured.
    if (iError == WSAETIMEDOUT) 
    {
    continue;
    }
    //terminate the ping if unable to receive reply.
    return 1;
    }
    printf("\niDataGet = %d \n",iDataGet);
    memcpy(&timestampreply,pReceiveBuffer+20,sizeof(IcmpHeader));//skip ip header(20 bytes)
    printIcmpHeader(timestampreply);
    int ts=GetTickCount()-timestampreply.originate_timestamp;
    printf(" sequence id %d use time %d\n", timestampreply.i_seq, ts);
    }
    return 0;
    }
      

  3.   

    //////////////////////////////////////////////////////////////////////////
    // //
    // SOCKET SUPPORT SECTION //
    // //
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // //
    // Send a PING Message //
    // //
    // Sends a PING message to the currently //
    // selected host. //
    // //
    // If icmpTracing is TRUE, //
    // increment and set icmpPingTTL to //
    // reach the next node in the Internet //
    // tree. Note: must timeout for a small//
    // period of time to allow TTL to //
    // complete. //
    // //
    // Start the timer and issue the Icmp Ping //
    // //
    ////////////////////////////////////////////////////发送PING消息包到目的主机
    void CEWDPingDlg::SendPing(void)
    { PingSent = TRUE;
    PingSocket.icmpCurSeq++;
    PingSocket.icmpCurId = (USHORT)GetCurrentProcessId(); PingSocket.icmpHostAddress = HostIPAddress();

    //如果目标地址为空,则返回
    if (PingSocket.icmpHostAddress == NULL)
    return;
    //如果icmpTracing为真,则必须将
    if (icmpTracing)
    {
    icmpPingTTL++;

        }
    //设定TTL
    if (PingSocket.SetTTL (icmpPingTTL) == SOCKET_ERROR)
    {
    PingSocket.DisplayError ("setsocket(TTL)",
     "CEWDPingDlg::SendPing");
    return;
    }
    //要设定一定的时间让TTL设定完成
    Sleep (100);

    //显示序列号,同时用蓝色尖头表示出来
    SetTraceSequence (PingSocket.icmpCurSeq, 
      m_TraceList.GetItemCount(), 
      Icon_BlueArrow); //设定地址
    PingSocket.icmpSockAddr.sin_family = PF_INET;
    PingSocket.icmpSockAddr.sin_addr.s_addr = PingSocket.icmpHostAddress;
    PingSocket.icmpSockAddr.sin_port = 0;
    //开始计时
    StartTimer();
    //调用PING函数发出PING命令
    if (PingSocket.Ping (pIcmpBuffer, icmpDataLen) == SOCKET_ERROR)
    PingSocket.DisplayError("Ping", "CEWDPingDlg::SendPing");}//////////////////////////////////////////////////////
    // //
    // HostIPAddress //
    // //
    // Return the IP Address for the curently //
    // selected host in Internet byte order. //
    // //
    // GetIPAddress leaves a copy of the address //
    // in icmpSockAddr and sets HostName to its //
    // DNS official name. //
    // //
    //////////////////////////////////////////////////////
    unsigned long CEWDPingDlg::HostIPAddress()
    { unsigned long iHostAddress; GetDlgItemText (IDC_DEST, HostName, MAXHOSTNAME); iHostAddress = PingSocket.GetIPAddress ((LPSTR)&HostName); if ((iHostAddress == INADDR_ANY) || (iHostAddress == NULL))
    {
    PingSocket.DisplayError ("gethostbyname", 
     "CEWDPingDlg::HostIPAddress");
    iHostAddress = NULL;
    }

    else

    SetDlgItemText (IDC_DEST, HostName); return iHostAddress;
    }