急急急!请问怎么用C语言实现ping命令?
急急急!请问怎么用C语言在windows下实现ping命令?
那些icmp协议又怎么定义了?
要加载那些头文件呢?
[解决办法]
N年前写的一个东西实现PING命令win下的、unix不会
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 ) ;}