首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

急请教如何用C语言实现ping命令

2012-08-13 
急急急!请问怎么用C语言实现ping命令?急急急!请问怎么用C语言在windows下实现ping命令?那些icmp协议又怎么

急急急!请问怎么用C语言实现ping命令?
急急急!请问怎么用C语言在windows下实现ping命令?
那些icmp协议又怎么定义了?
要加载那些头文件呢?

[解决办法]
N年前写的一个东西实现PING命令win下的、unix不会

C/C++ code
USHORT GetCheckSum ( LPBYTE lpBuf, DWORD dwSize ){    // 设置目标地址    SOCKADDR_IN DestSockAddr ;    DestSockAddr.sin_family = AF_INET ;    DestSockAddr.sin_addr.s_addr = inet_addr( lpDestIp ) ;    DestSockAddr.sin_port = htons ( 0 ) ;    // 创建ICMP回显请求包    char ICMPPack[ICMP_PACK_SIZE] = {0} ;    PICMP_HEADER pICMPHeader = (PICMP_HEADER)ICMPPack ;    pICMPHeader->bType = 8 ;    pICMPHeader->bCode = 0 ;    pICMPHeader->nId = (USHORT)::GetCurrentProcessId() ;    pICMPHeader->nCheckSum = 0 ;    pICMPHeader->nTimeStamp = 0 ;    memset ( &(ICMPPack[ICMP_HEADER_SIZE]), 'E', ICMP_DATA_SIZE ) ;    // 填充数据部分,内容任意    // 初始化WinSock库    WORD wVersionRequested = MAKEWORD( 2, 2 );    WSADATA wsaData;    if ( WSAStartup( wVersionRequested, &wsaData ) != 0 )    {        return FALSE ;    }    // 创建原始套接字    SOCKET    RawSock = socket ( AF_INET, SOCK_RAW, IPPROTO_ICMP ) ;    if ( RawSock == INVALID_SOCKET )    {        printf ( "Create socket error: %d\n", GetLastError()) ;        return FALSE ;    }        // 设置接收超时为1秒    int nTime = 1000 ;    int ret = ::setsockopt ( RawSock, SOL_SOCKET,SO_RCVTIMEO, (char*)&nTime, sizeof(nTime));        char szRecvBuf [ DEF_BUF_SIZE] ;    SOCKADDR_IN    SourSockAddr ;    for ( int i = 0 ; i < 4; i++ )    {        pICMPHeader->nCheckSum = 0 ;                // 初始时校验值为0        pICMPHeader->nSequence = i ;                // 序号        pICMPHeader->nTimeStamp = ::GetTickCount() ;// 当前时间        // 计算校验值,校验值要在ICMP数据报创建完才能计算        pICMPHeader->nCheckSum = GetCheckSum ( (LPBYTE)ICMPPack, ICMP_PACK_SIZE ) ;                // 发送ICMP数据包        int nRet = ::sendto ( RawSock, ICMPPack, ICMP_PACK_SIZE,0,(SOCKADDR*)&DestSockAddr, sizeof(DestSockAddr) ) ;        if ( nRet == SOCKET_ERROR )        {            printf ( "sendto error: %d\n",GetLastError()) ;            return FALSE ;        }        // 接收ICMP响应        int nLen = sizeof(SourSockAddr) ;        nRet = ::recvfrom ( RawSock, szRecvBuf, DEF_BUF_SIZE,0,(SOCKADDR*)&SourSockAddr, &nLen ) ;        if ( nRet == SOCKET_ERROR )        {            if ( ::WSAGetLastError() == WSAETIMEDOUT )            {                printf ( "Request Timeout: %d\n",GetLastError()) ;                continue ;            }            else            {                printf ( "recvfrom error: %d\n",GetLastError() ) ;                return FALSE ;            }        }        // 计算ICMP数据报的时间差        int nTime = ::GetTickCount() - pICMPHeader->nTimeStamp ;        int nRealSize = nRet - IP_HEADER_SIZE - ICMP_HEADER_SIZE ;        if ( nRealSize < 0  )        {            printf ( "To less recv bytes!\n" ) ;            continue ;        }        // 检测是否当前所发出的ICMP响应包        PICMP_HEADER pRecvHeader = (PICMP_HEADER)(szRecvBuf+IP_HEADER_SIZE) ;        if ( pRecvHeader->bType != 0 )        {            printf ( "Not ICMP respond type: %d\n",GetLastError()) ;            return FALSE ;        }        if ( pRecvHeader->nId != ::GetCurrentProcessId () )        {            printf ( "not valid id: %d\n",GetLastError()) ;            return FALSE ;        }        printf ( "%d bytes replay from %s : bytes=%d time=%dms\n", \            nRet, inet_ntoa(SourSockAddr.sin_addr), nRealSize, nTime ) ;        ::Sleep ( 1000 ) ;    }        closesocket ( RawSock ) ;    WSACleanup () ;    return TRUE ;}USHORT GetCheckSum ( LPBYTE lpBuf, DWORD dwSize ){    DWORD    dwCheckSum = 0 ;    USHORT* lpWord = (USHORT*)lpBuf ;    // 累加    while ( dwSize > 1 )    {        dwCheckSum += *lpWord++ ;        dwSize -= 2 ;    }    // 如果长度是奇数    if ( dwSize == 1 )    {        dwCheckSum += *((LPBYTE)lpWord) ;    }    // 高16位和低16位相加    dwCheckSum = ( dwCheckSum >> 16 ) + ( dwCheckSum & 0xFFFF ) ;    // 取反    return (USHORT)(~dwCheckSum ) ;} 

热点排行
Bad Request.