c/c++ 实现ping程序

来源:互联网 发布:java连接mysql url 编辑:程序博客网 时间:2024/05/29 10:00
#ifndef _PING_H_#define _PING_H#include <WinSock2.h>#include <stdlib.h>#include <stdio.h>#pragma comment(lib, "ws2_32.lib")#define ICMP_SIZE 32//ICMP header structuretypedef struct _ICMP_HDR{BYTEtype;BYTEcode;USHORTchecksum;USHORT  id;USHORT  seq;}ICMP_HDR;//ping option informatiom structuretypedef struct  _IP_OPTION_INFORMATION{unsigned char ttl;unsigned char tos;unsigned char flags;unsigned char options_size;unsigned char *options_data;}IP_OPTION_INFORMATION, *PIP_OPTION_INFORMATION;//ping echo reply structuretypedef struct _IP_ECHO_REPLY {DWORD address;unsigned long status;unsigned long round_trip_time;unsigned long data_size;unsigned long reserved;void *data;IP_OPTION_INFORMATION options;}IP_ECHO_REPLY, * PIP_ECHO_REPLY;BOOL InitWinsock(void);BOOL ResolveIp(char* hostname);void PrinfHelp();BOOL ResolveParam(int argc, char** argv  ,char* hostname, unsigned int& ncount, unsigned int& timeout);typedef HANDLE (WINAPI* picf)(void);typedef BOOL   (WINAPI* pich)(HANDLE);typedef DWORD  (WINAPI* pise)(HANDLE, struct in_addr, LPVOID, WORD, PIP_OPTION_INFORMATION  ,LPVOID, DWORD, DWORD);#endif
#include "Ping.h"int main(int argc, char* argv[]){ PIP_ECHO_REPLY pIpe= NULL; struct in_addr hostaddr; HINSTANCE hIcmp= NULL; HANDLE hPing= NULL; DWORD status= 0; char szHostName[MAX_PATH]= {0}; char ping_buf[ICMP_SIZE]= {0}; char buf[512]= {0}; unsigned int ncount; unsigned int timeout; unsigned int index= 0; int packets_received= 0; int min_rtt= -1; int max_rtt= 0; int average_rtt= 0; float percent_lost= 0.0; BOOL bResult= FALSE; bResult= ResolveParam(argc, argv, szHostName, ncount, timeout); if (bResult== FALSE) { PrinfHelp(); return 0; } bResult=InitWinsock(); if (bResult== FALSE) { return 0; } hIcmp= LoadLibrary("ICMP.DLL"); if (hIcmp== NULL) { printf("Failed to load ICMP.DLL: %d\n", GetLastError()); return 0; } picf pIcmpCreateFile= (picf)GetProcAddress(hIcmp, "IcmpCreateFile"); pich pIcmpCloseHandle= (pich)GetProcAddress(hIcmp, "IcmpCloseHandle"); pise pIcmpSendEcho= (pise)GetProcAddress(hIcmp, "IcmpSendEcho"); if (pIcmpCreateFile== NULL|| pIcmpCloseHandle== NULL || pIcmpSendEcho== NULL) { printf("Failed to load ICMP.DLL APIs\n"); return 0; } hPing= pIcmpCreateFile(); if (hPing== INVALID_HANDLE_VALUE) { printf("Failed to open ICMP service\n"); goto cleanup; } memset(ping_buf, '\xAA', sizeof(ping_buf)); pIpe= (PIP_ECHO_REPLY)GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT , sizeof(IP_ECHO_REPLY)+ICMP_SIZE+1); if (pIpe== NULL) { printf("Failed to allocate ping packet buffer(PIP_ECHO_REPLY struct)\n"); goto cleanup; } //resolve the hostname if (!ResolveIp(szHostName)) { printf("Could not resolve host \"%s\"\n", szHostName); goto cleanup; } //convert the hostname pointer to usable data hostaddr.S_un.S_addr= inet_addr(szHostName); pIpe->data= ping_buf; printf("\nPinging %s with %d bytes of data:\n", szHostName, ICMP_SIZE); //keep pinging until user stops or count runs out for (index= 0; index< ncount; index++) { status= pIcmpSendEcho(hPing, hostaddr, ping_buf, sizeof(ping_buf), NULL , pIpe,sizeof(IP_ECHO_REPLY)+sizeof(ping_buf), timeout); if (status) { printf("Reply from %s: bytes=%d time=%dms TTL=%d %s\n", szHostName , pIpe->data_size, pIpe->round_trip_time, pIpe->options.ttl ,(pIpe->data_size<=0)?"(Destination Host Unreachable)":""); if (pIpe->round_trip_time>max_rtt) { max_rtt= pIpe->round_trip_time; } else if (pIpe->round_trip_time<min_rtt || min_rtt== -1) { min_rtt= pIpe->round_trip_time; } if (pIpe->round_trip_time> 0) { average_rtt += pIpe->round_trip_time; } } else { printf("Request timed out.\n"); } if (status && pIpe->data_size>0) { ++packets_received; } if (index!= ncount-1) {Sleep(1000); } } //prin the final results percent_lost= (float)((index-packets_received)/index)*100; printf("\nPing statistics for %s:\n", szHostName); printf("    Packets:Sent = %d, Received = %d, Lost = %d (%d%% loss),\n" , index, packets_received, (index-packets_received), (int)percent_lost); printf("Approximate round trip time in milli-seconds:\n"); average_rtt= average_rtt/index; printf("    Minimum = %dms, Maximum = %dms, Average = %dms\n", min_rtt, max_rtt, average_rtt);cleanup: if (hIcmp) { FreeLibrary(hIcmp); } if (hPing) { pIcmpCloseHandle(hPing); } if (pIpe) { GlobalFree(pIpe); } return 0;}BOOL InitWinsock(void){WSADATA wsadata;int ret;ret=WSAStartup(MAKEWORD(2,2), &wsadata);if (ret!= 0){printf("WSAStartip failed: %d\n", GetLastError());return FALSE;}return TRUE;}BOOL ResolveIp(char* hostname){struct hostent* host;struct in_addr in;host= gethostbyname(hostname);if (host== NULL){printf("gethostbyname failed: %d\n", GetLastError());return FALSE;}in.s_addr=*(u_long*)host->h_addr_list[0];strcpy(hostname, inet_ntoa(in));return TRUE;}void PrinfHelp(){printf("Usage: Ping.exe [-n count] [-w timeout] -h target_name\n");printf("-n countNumber of echo request to echo.\n");printf("-w timeoutTimeout in milliseconds to wait for each reply.\n");printf("-h target_nameTarget hostname or ip address.\n\n");}BOOL ResolveParam( int argc, char** argv ,char* hostname, unsigned int& ncount, unsigned int& timeout ){char szCount[MAX_PATH]= {0};char szTimeout[MAX_PATH]= {0};int i= 0;if (argc<2){return FALSE;}for (int i=1; i<argc; i++){if (stricmp(argv[i-1], "-n")== 0){if (argv[i][0] != '-'){memcpy(szCount, argv[i], strlen(argv[i]));}}else if (stricmp(argv[i-1], "-w")== 0){if (argv[i][0] != '-'){memcpy(szTimeout, argv[i], strlen(argv[i]));}}else if (stricmp(argv[i-1], "-h")== 0){if (argv[i][0] != '-'){memcpy(hostname, argv[i], strlen(argv[i]));}}}if (strlen(szCount)== 0){ncount= 4;}else if (strlen(szCount)> 9){printf("Max count of 4,294,967,295\n");return FALSE;}else{for(i=0; szCount[i] != '\0'; ++i)if(!isdigit(szCount[i])){printf("Enter an integer for the count\n");return FALSE;}ncount= atol(szCount);}if (strlen(szTimeout)== 0){timeout= 1000;}else if (strlen(szTimeout)>6){printf("Timeout too large\n");return FALSE;}else{// check the bufferfor(i=0; szTimeout[i] != '\0'; ++i)if(!isdigit(szTimeout[i])){printf("Enter a valid timeout\n");return FALSE;}// scan in the valuetimeout= atol(szTimeout);timeout *= 1000; // convert to milliseconds}return TRUE;}


0 0
原创粉丝点击