user-0 提问: 如何实现向多个IP的ping指令,并将ping的结果集保存在文件中

回复:
user: user-0
content: 这么多啊，大哥这是什么级别了

user: user-1
content: 这需求也是坑死爹了。 连续不同的IP呢？ 丢包超时呢？  让你看下这个代码 //icmpPing.h #include <tchar.h> #include <stdio.h> #include <WinSock2.h>  #ifdef ICMPPING_EXPORTS #define ICMPPING_API __declspec(dllexport) #else #define ICMPPING_API __declspec(dllimport) #endif  DWORD ICMPPING_API icmp_ping(LPSTR szIP,int* needTime,int sendDataSize, int iPingTimeout);  //icmpPing.cpp  unsigned long ResolveIP(LPSTR strIP) { 	unsigned long ip; 	ip =(IPAddr)inet_addr(strIP); 	return ip; }  DWORD icmp_ping(LPSTR szIP,int* needTime,int sendDataSize, int iPingTimeout) { 	//Task 1: Open ICMP Handle 	//Task 2: Create Structure to receive ping reply 	//Task 3: SendPing （SendEcho） 	//Task 4: Close ICMP Handle 	//Task 5: Return RoundTripTime  	int dataSize = sendDataSize / sizeof(TCHAR) + 1; 	TCHAR *SendData = new TCHAR[sendDataSize];  	for (int i = 0; i != dataSize; ++i) 	{ 		SendData[i] = (TCHAR)65; 	} 	SendData[dataSize - 1] = (TCHAR)0;  	DWORD    SendDataSize = dataSize; 	LPVOID    ReplyBuffer = NULL; 	DWORD    ReplySize = 0;  	ReplySize = SendDataSize + sizeof(ICMP_ECHO_REPLY); 	ReplyBuffer = new TCHAR[ReplySize];  	HANDLE icmphandle = IcmpCreateFile(); 	if(INVALID_HANDLE_VALUE == icmphandle){ 		delete SendData;  		return GetLastError(); 	} 	DWORD nRet = IcmpSendEcho(icmphandle,ResolveIP(szIP), SendData, (WORD)SendDataSize, NULL, ReplyBuffer,ReplySize,iPingTimeout); 	PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer; 	if(pEchoReply->Status != 0){ 		std::cout<<"ping error = "<<GetLastError()<<std::endl; 		*needTime = 10000; 	}else{ 		*needTime = pEchoReply->RoundTripTime; 	} 	IcmpCloseHandle(icmphandle); 	ULONG   Status = pEchoReply->Status; 	delete SendData; 	delete ReplyBuffer; 	return Status; }  //icmpUtility.h #pragma once  #ifdef ICMPUTILITY_EXPORTS #define ICMP_API __declspec(dllexport) #else #define ICMP_API __declspec(dllimport) #endif  #ifndef ICMPUTILITY_H_ #define ICMPUTILITY_H_ #include <string> #include <functional>    struct ICMP_API IcmpResponse{ 	int m_milliseconds; 	std::string m_ip; 	unsigned long m_status; };  typedef ICMP_API std::function<void(IcmpResponse)> IcmpCallback;  struct ICMP_API IcmpParam{ 	std::wstring m_ip; 	IcmpCallback m_callback; }; bool ICMP_API startIcmp(IcmpParam param); #endif  //icmpUtility.cpp  UINT __stdcall icmpThreadProc(void* lpParam) { 	IcmpParam* paramPtr = (IcmpParam*)lpParam; 	if(NULL == paramPtr){ 		return 1; 	} 	USES_CONVERSION; 	LPSTR ip = W2A(paramPtr->m_ip.c_str()); 	IcmpResponse resp; 	resp.m_milliseconds = 10000; 	resp.m_status = icmp_ping(ip,&resp.m_milliseconds,1,10000); 	resp.m_ip = ip; 	switch(resp.m_status) 	{ 	case IP_SUCCESS:{}break; 	case IP_BUF_TOO_SMALL:{std::cout<<"缓冲太小"<<std::endl;}break; 	case IP_DEST_NET_UNREACHABLE:{std::cout<<"目标网络不可达"<<resp.m_milliseconds<<std::endl;}break; 	case IP_DEST_HOST_UNREACHABLE:{std::cout<<"目标主机不可达"<<resp.m_milliseconds<<std::endl;}break; 	case IP_DEST_PROT_UNREACHABLE:{std::cout<<"目的地址不可达 "<<resp.m_milliseconds<<std::endl;}break; 	case IP_DEST_PORT_UNREACHABLE:{std::cout<<"目标端口不可达"<<std::endl;}break; 	case IP_NO_RESOURCES:{std::cout<<"ip资源不足"<<std::endl;}break; 	case IP_BAD_OPTION:{std::cout<<"指定了错误的IP选项"<<std::endl;}break; 	case IP_HW_ERROR:{std::cout<<"一个硬件错误"<<std::endl;}break; 	case IP_PACKET_TOO_BIG:{std::cout<<"包太大"<<std::endl;}break; 	case IP_REQ_TIMED_OUT:{std::cout<<"请求超时"<<std::endl;}break; 	case IP_BAD_REQ:{std::cout<<"一个坏的请求"<<std::endl;}break; 	case IP_BAD_ROUTE:{std::cout<<"一个糟糕的路线"<<std::endl;}break; 	case IP_TTL_EXPIRED_TRANSIT:{std::cout<<"在传输过程中的生存时间（TTL）的过期"<<std::endl;}break; 	case IP_TTL_EXPIRED_REASSEM:{std::cout<<"在碎片重组过程中的生存时间过期"<<std::endl;}break; 	case IP_PARAM_PROBLEM:{std::cout<<"一个参数的问题"<<std::endl;}break; 	case IP_SOURCE_QUENCH:{std::cout<<"数据报到达太快，处理和数据报可能被丢弃"<<std::endl;}break; 	case IP_OPTION_TOO_BIG:{std::cout<<"一个IP选项是太大了"<<std::endl;}break; 	case IP_BAD_DESTINATION:{std::cout<<"一个坏的目的地"<<std::endl;}break; 	case IP_GENERAL_FAILURE:{std::cout<<"一般故障。这个错误可以返回一些畸形的ICMP数据包"<<std::endl;}break; 	} 	if(paramPtr->m_callback){ 		paramPtr->m_callback(resp); 	} 	delete paramPtr; 	return 0; }  bool startIcmp(IcmpParam param) { 	IcmpParam* lpParam = new IcmpParam; 	lpParam->m_callback = param.m_callback; 	lpParam->m_ip = param.m_ip; 	::_beginthreadex(NULL,0,icmpThreadProc,lpParam,0,0); 	return TRUE; }

user: user-0
content: 哈，老师，学习了……谢谢！

user: user-2
content: 仅供参考：#include <windows.h> #include <stdio.h> #include <string.h> char YN(int k) {     FILE *f;     char fn[40];     char ln[80];     char yn;     int n;      yn='N';     sprintf(fn,"d:\\ping%d.txt",k);     f=fopen(fn,"r");     if (NULL!=f) {         n=0;         while (1) {             if (NULL==fgets(ln,80,f)) break;//             if (strstr(ln,"ms ")) {                 yn='Y';                 break;//             }             n++;             if (n>=4) break;//         }         fclose(f);     }     return yn; } void main(int argc,char **argv) {     char cmdstr[256];     int i;     int IP[3];     char c;      if (argc<2) {     USAGE:         printf("Usage example:\n    %s 192.168.60.\nto test 192.168.60.1-254\n",argv[0]);         return;     }     if (4==sscanf(argv[1],"%d.%d.%d%c",&IP[0],&IP[1],&IP[2],&c)) {         if (0<=IP[0] && IP[0]<=255          && 0<=IP[1] && IP[1]<=255          && 0<=IP[2] && IP[2]<=255          && '.'==c) {             for (i=1;i<255;i++) {                 sprintf(cmdstr,"cmd /c ping %s%d -n 1 -w 1000 >d:\\ping%d.txt",argv[1],i,i);                 WinExec(cmdstr,SW_HIDE);             }             Sleep(3000);             for (i=1;i<255;i++) {                 printf("%c %s%d\n",YN(i),argv[1],i);             }             Sleep(3000);             WinExec("cmd /c del /q d:\\ping*.txt",SW_HIDE);         } else goto USAGE;     } else goto USAGE; }

user: user-0
content: 这个有用嘛，我是要在c语言的函数代码来实现ping命令的循环多个ip的

user: user-3
content: 装一个nmap，然后调用nmap的ping扫描结果！哇哈哈！我真是太聪明了。

user: user-2
content: 引用 4 楼 sinat_27421313 的回复:谢谢老师，受教了，看了你的代码思路更清晰了，只是有些还看不懂，测试下有点问题我这边，有些地方注释更好点…… 代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

user: user-0
content: 谢谢老师，受教了，看了你的代码思路更清晰了，只是有些还看不懂，测试下有点问题我这边，有些地方注释更好点……