用vs2010的MFC实现 使用icmp协议查找局域网内的活动主机 对网络编程比较迷茫,请教设计程序,其功能是发送ICMP数据包,以获取局域网中的活动主机,并将结果显示vs2010 MFC图形界面上,要能直接运行的 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 网络使用ICMP发现局域网内活动主机 http://wenku.baidu.com/link?url=ImEIZVy3K8W31FWMo95ePzCZdKz5TJ6UcMH3b-5lfft8LDaaqHZPQViNrCChgqjfIyH5bnd7vVaaHmRtRxS-BcnkHlv5wPjanegGRKLYegW 我需要把IP地址运行结果输出在一个图形界面上,就是用把运行结果放在mfc图形界面上这个报告上面是没有图形界面的。。 http://wangbaiyuan.cn/c-activity-host-scans.html你自己把控制台的修改成GUI的即可,应该还是很简单的~ 参见msdn例程 SendARP()ms-help://MS.MSDNQTR.v90.chs/iphlp/iphlp/sendarp.htm//The following code demonstrates how to obtain the hardware or media access control (MAC) address associated with a specified IPv4 address./* sendarp.c * * Link with wsock2.lib and iphlpapi.lib */#include <winsock2.h>#include <iphlpapi.h>#include <stdio.h>void usage(char *pname){ printf("Usage: %s [options] ip-address\n", pname); printf("\t -h \t\thelp\n"); printf("\t -l length \tMAC physical address length to set\n"); printf("\t -s src-ip \tsource IP address\n"); exit(1);}int __cdecl main(int argc, char **argv){ DWORD dwRetVal; IPAddr DestIp = 0; IPAddr SrcIp = 0; /* default for src ip */ ULONG MacAddr[2]; /* for 6-byte hardware addresses */ ULONG PhysAddrLen = 6; /* default to length of six bytes */ char *DestIpString = NULL; char *SrcIpString = NULL; BYTE *bPhysAddr; int i; if (argc > 1) { for (i = 1; i < argc; i++) { if ((argv[i][0] == '-') || (argv[i][0] == '/')) { switch (tolower(argv[i][1])) { case 'l': PhysAddrLen = (ULONG) atol(argv[++i]); break; case 's': SrcIpString = argv[++i]; SrcIp = inet_addr(SrcIpString); break; case 'h': default: usage(argv[0]); break; } /* end switch */ } else DestIpString = argv[i]; } /* end for */ } else usage(argv[0]); if (DestIpString == NULL || DestIpString[0] == '\0') usage(argv[0]); DestIp = inet_addr(DestIpString); memset(&MacAddr, 0xff, sizeof (MacAddr)); printf("Sending ARP request for IP address: %s\n", DestIpString); dwRetVal = SendARP(DestIp, SrcIp, &MacAddr, &PhysAddrLen); if (dwRetVal == NO_ERROR) { bPhysAddr = (BYTE *) & MacAddr; if (PhysAddrLen) { for (i = 0; i < (int) PhysAddrLen; i++) { if (i == (PhysAddrLen - 1)) printf("%.2X\n", (int) bPhysAddr[i]); else printf("%.2X-", (int) bPhysAddr[i]); } } else printf ("Warning: SendArp completed successfully, but returned length=0\n"); } else { printf("Error: SendArp failed with error: %d", dwRetVal); switch (dwRetVal) { case ERROR_GEN_FAILURE: printf(" (ERROR_GEN_FAILURE)\n"); break; case ERROR_INVALID_PARAMETER: printf(" (ERROR_INVALID_PARAMETER)\n"); break; case ERROR_INVALID_USER_BUFFER: printf(" (ERROR_INVALID_USER_BUFFER)\n"); break; case ERROR_BAD_NET_NAME: printf(" (ERROR_GEN_FAILURE)\n"); break; case ERROR_BUFFER_OVERFLOW: printf(" (ERROR_BUFFER_OVERFLOW)\n"); break; case ERROR_NOT_FOUND: printf(" (ERROR_NOT_FOUND)\n"); break; default: printf("\n"); break; } } return 0;}如果采用单线程方式,会很慢,从1-255顺序发送的话。可以为了节省时间来改成多线程方式,分成1-64;65-127;128-191;192-255四段区间,用4个线程同时扫描------------------------typedef struct ipmac { char szIp[16]; char szMac[6]; }IPMAC; IPMAC host[255]; int k=0; CRITICAL_SECTION cs; /*线程函数,用来查询IP对应的MAC地址*/ DWORD WINAPI ArpThread(LPVOID lParam) { char * szIp=(char *)lParam; ULONG pMac[2]; ULONG pulen=6; int ret; TRACE(szIp); if ((ret=SendARP(inet_addr(szIp),0,pMac,&pulen))==0) { EnterCriticalSection(&cs); //多线程同步,呵呵:0 strcpy(host[k].szIp,szIp); PBYTE pbyte=(PBYTE)pMac; for (int i=0;i<5;i++) { host[k].szMac[i]=pbyte[i]; TRACE("%02X-",pbyte[i]); } TRACE("%02X",pbyte[5]); host[k].szMac[5]=pbyte[5]; k++; LeaveCriticalSection(&cs); } else { TRACE("SendARP Error %d",ret); } return 0; } /*枚举局域网内所有主机,并将IP/MAC对插入ListBox中显示*/ void CTestArpDlg::OnButton1() { // TODO: Add your control notification handler code here HANDLE hthread[254]; CString IpSuffix="192.168.10."; CString strIp[254]; InitializeCriticalSection(&cs); for (int i=0;i<254;i++) { strIp[i].Format("%d",i+1); strIp[i]=IpSuffix+strIp[i]; hthread[i]=CreateThread(NULL,0,ArpThread,strIp[i].GetBuffer(0),0,NULL); } /*呵呵,因为一次只能等待 64个内核对象,所以只有分几次了*/ /*当然也可以用循环了*/ WaitForMultipleObjects(64,hthread,TRUE,INFINITE); WaitForMultipleObjects(64,&hthread[64],TRUE,INFINITE); WaitForMultipleObjects(64,&hthread[128],TRUE,INFINITE); WaitForMultipleObjects(62,&hthread[192],TRUE,INFINITE); DeleteCriticalSection(&cs); CString temp; for (i=0;i { PBYTE pmac=(PBYTE)host[i].szMac; temp.Format("%s(%02x-%02x-%02x-%02x-%02x-%02x)",host[i].szIp,pmac[0],pmac[1],pmac[2],pmac[3],pmac[4],pmac[5]); m_list.AddString(temp); } } 萌新楼主刚学网络这一块,需要将ip结果输出到图形界面,对于GUI实在无感 仅供参考:#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;} 用ICMP探测主机还是比较慢的,如果摊上一个A类或者B类的子网,你的程序可能需要很长时间才能够返回。推荐使用ARP协议去探测主机,只需要伪造一个你是网关的ARP发送出去,然后局域网内的所有主机都会给你发送数据,你就可以获得所有主机的IP和MAC了。这个过程很快,几秒钟就可以了 这个好像没有用到icmp??根本没有数据报的发送接收解析,而且我只是要把上面的代码加上图形界面 我知道ARP比较快,但是程序要求就是icmp,而且需要图形界面,不是我能决定的 关于 vc++ mfc下如何集成 propertyGrid 控件 如下问题如何解决,请高手指教 vc# web开发与wpf开发是什么?mfc呢? 请问是不是嵌套有问题?? 用ATL写一个服务程序,它的log放在哪里了,找不到日志文件?用OutputDebugString()送到哪里了?还有原来析构函数中的内容写在哪里?谢谢 牛人请进!!关于两张网卡选择哪一张发送资料的问题??(1000分求解) 如何给CEditCtrl设置颜色? 邮件问题(高分相送) 关于DCOM的难题 OPC客户端 MFC界面里子对话框实现通信 关于CStdioFile读文件的问题
你自己把控制台的修改成GUI的即可,应该还是很简单的~
//The following code demonstrates how to obtain the hardware or media access control (MAC) address associated with a specified IPv4 address./* sendarp.c
*
* Link with wsock2.lib and iphlpapi.lib
*/#include <winsock2.h>
#include <iphlpapi.h>
#include <stdio.h>void usage(char *pname)
{
printf("Usage: %s [options] ip-address\n", pname);
printf("\t -h \t\thelp\n");
printf("\t -l length \tMAC physical address length to set\n");
printf("\t -s src-ip \tsource IP address\n");
exit(1);
}int __cdecl main(int argc, char **argv)
{
DWORD dwRetVal;
IPAddr DestIp = 0;
IPAddr SrcIp = 0; /* default for src ip */
ULONG MacAddr[2]; /* for 6-byte hardware addresses */
ULONG PhysAddrLen = 6; /* default to length of six bytes */ char *DestIpString = NULL;
char *SrcIpString = NULL; BYTE *bPhysAddr;
int i; if (argc > 1) {
for (i = 1; i < argc; i++) {
if ((argv[i][0] == '-') || (argv[i][0] == '/')) {
switch (tolower(argv[i][1])) {
case 'l':
PhysAddrLen = (ULONG) atol(argv[++i]);
break;
case 's':
SrcIpString = argv[++i];
SrcIp = inet_addr(SrcIpString);
break;
case 'h':
default:
usage(argv[0]);
break;
} /* end switch */
} else
DestIpString = argv[i];
} /* end for */
} else
usage(argv[0]); if (DestIpString == NULL || DestIpString[0] == '\0')
usage(argv[0]); DestIp = inet_addr(DestIpString); memset(&MacAddr, 0xff, sizeof (MacAddr)); printf("Sending ARP request for IP address: %s\n", DestIpString); dwRetVal = SendARP(DestIp, SrcIp, &MacAddr, &PhysAddrLen); if (dwRetVal == NO_ERROR) {
bPhysAddr = (BYTE *) & MacAddr;
if (PhysAddrLen) {
for (i = 0; i < (int) PhysAddrLen; i++) {
if (i == (PhysAddrLen - 1))
printf("%.2X\n", (int) bPhysAddr[i]);
else
printf("%.2X-", (int) bPhysAddr[i]);
}
} else
printf
("Warning: SendArp completed successfully, but returned length=0\n"); } else {
printf("Error: SendArp failed with error: %d", dwRetVal);
switch (dwRetVal) {
case ERROR_GEN_FAILURE:
printf(" (ERROR_GEN_FAILURE)\n");
break;
case ERROR_INVALID_PARAMETER:
printf(" (ERROR_INVALID_PARAMETER)\n");
break;
case ERROR_INVALID_USER_BUFFER:
printf(" (ERROR_INVALID_USER_BUFFER)\n");
break;
case ERROR_BAD_NET_NAME:
printf(" (ERROR_GEN_FAILURE)\n");
break;
case ERROR_BUFFER_OVERFLOW:
printf(" (ERROR_BUFFER_OVERFLOW)\n");
break;
case ERROR_NOT_FOUND:
printf(" (ERROR_NOT_FOUND)\n");
break;
default:
printf("\n");
break;
}
} return 0;
}
如果采用单线程方式,会很慢,从1-255顺序发送的话。
可以为了节省时间来改成多线程方式,分成1-64;65-127;128-191;192-255四段区间,用4个线程同时扫描
------------------------typedef struct ipmac
{
char szIp[16];
char szMac[6];
}IPMAC;
IPMAC host[255];
int k=0;
CRITICAL_SECTION cs;
/*线程函数,用来查询IP对应的MAC地址*/
DWORD WINAPI ArpThread(LPVOID lParam)
{
char * szIp=(char *)lParam;
ULONG pMac[2];
ULONG pulen=6;
int ret;
TRACE(szIp);
if ((ret=SendARP(inet_addr(szIp),0,pMac,&pulen))==0)
{
EnterCriticalSection(&cs); //多线程同步,呵呵:0
strcpy(host[k].szIp,szIp);
PBYTE pbyte=(PBYTE)pMac;
for (int i=0;i<5;i++)
{
host[k].szMac[i]=pbyte[i];
TRACE("%02X-",pbyte[i]);
}
TRACE("%02X",pbyte[5]);
host[k].szMac[5]=pbyte[5];
k++;
LeaveCriticalSection(&cs);
}
else
{
TRACE("SendARP Error %d",ret);
}
return 0;
}
/*枚举局域网内所有主机,并将IP/MAC对插入ListBox中显示*/
void CTestArpDlg::OnButton1()
{
// TODO: Add your control notification handler code here
HANDLE hthread[254];
CString IpSuffix="192.168.10.";
CString strIp[254];
InitializeCriticalSection(&cs);
for (int i=0;i<254;i++)
{
strIp[i].Format("%d",i+1);
strIp[i]=IpSuffix+strIp[i];
hthread[i]=CreateThread(NULL,0,ArpThread,strIp[i].GetBuffer(0),0,NULL);
}
/*呵呵,因为一次只能等待 64个内核对象,所以只有分几次了*/
/*当然也可以用循环了*/
WaitForMultipleObjects(64,hthread,TRUE,INFINITE);
WaitForMultipleObjects(64,&hthread[64],TRUE,INFINITE);
WaitForMultipleObjects(64,&hthread[128],TRUE,INFINITE);
WaitForMultipleObjects(62,&hthread[192],TRUE,INFINITE);
DeleteCriticalSection(&cs);
CString temp;
for (i=0;i {
PBYTE pmac=(PBYTE)host[i].szMac;
temp.Format("%s(%02x-%02x-%02x-%02x-%02x-%02x)",host[i].szIp,pmac[0],pmac[1],pmac[2],pmac[3],pmac[4],pmac[5]);
m_list.AddString(temp);
}
}
萌新楼主刚学网络这一块,需要将ip结果输出到图形界面,对于GUI实在无感
#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;
}
这个好像没有用到icmp??根本没有数据报的发送接收解析,而且我只是要把上面的代码加上图形界面
我知道ARP比较快,但是程序要求就是icmp,而且需要图形界面,不是我能决定的