读书人

小弟我自己写的扫描局域网IP的程序有

发布时间: 2012-03-08 13:30:13 作者: rapoo

我自己写的扫描局域网IP的程序,有点问题,帮我看看!!

有时候可以把局域内的全部IP都扫描出来,但是有时候只能扫描到自己的IP地址!!!

请帮我看看程序有什么问题!!!

#include "stdio.h"
#include "stdlib.h"
#include "winsock2.h"
#include "Iphlpapi.h"
#include "time.h"

#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib,"iphlpapi.lib")

char *net_id;
char check_ip[256][10];
SOCKETsock;
WSADATAwsa;
HOSTENT *host;
IPAddr now_ip;
clock_tstart_time,end_time;
float costtime;
intThreadnum = 0;
inthostnum = 0;

// 自定义函数原形声明
void usage(char *);

void Display_Face();

void Display_Welcome();

void check_input(int argc,char**argv);

void check_socket();

void Get_Mac(int );

void Get_Host_Name();

DWORD WINAPI scan_lan(LPVOID lp);


int main(int argc,char **argv)
{
if ( argc < 2)
{
usage(argv[0]);
}
check_input(argc,argv);

check_socket();

system("cls");

Display_Welcome();

Display_Face();

start_time = clock();

for ( int i = 1; i <= 254; i++)
{
CreateThread(NULL,0,scan_lan,&i,0,NULL);
Threadnum++;
Sleep(10);
}

end_time = clock();

costtime = (float)(end_time - start_time) / CLOCKS_PER_SEC;
printf("%26s\n本次扫描用时 %.4f Seconds\n"," ",costtime);
printf("\n局域网内共有%3d个主机存活\n",hostnum);
Sleep(100);
return 0;
}


void check_input(int argc,char **argv) //检测输入数据
{
net_id = &argv[1][0];
}

void check_socket() //启动socket库
{
if ( WSAStartup( MAKEWORD(2,0),&wsa) != 0)
{
printf("Socket load fail...\n");

return ;
}

sock = socket(AF_INET,SOCK_STREAM,0);
if (sock == INVALID_SOCKET)
{
printf("Socket build faill...\n");

return ;
}
}

void Get_Mac(int host_id) //获取主机MAC
{

ULONGmac[2];
ULONGmac_len;

memset(mac,0xff,sizeof(mac));
mac_len = 6;

sprintf(check_ip[host_id],"%s.%d",net_id,host_id);

printf("Scaning ip:%s\r",check_ip[host_id]);
now_ip = inet_addr(check_ip[host_id]);

DWORD hr = SendARP( now_ip, 0, mac, &mac_len);

if (hr ==NO_ERROR)
{
hostnum ++;

unsigned char * mac_addr=(unsigned char*)mac;

Get_Host_Name(); //如果主机存活,获取主机名

printf("%10s\t\t%10s.%d\t\t%02X-%02X-%02X-%02X-%02X-%02X\n",host->h_name ,net_id,host_id,mac_addr[0],mac_addr[1],mac_addr[2],mac_addr[3],mac_addr[4],mac_addr[5]);
}
InterlockedExchangeAdd((long *)&Threadnum,-1);

}

void Get_Host_Name() //根据IP地址,获取对应的主机名
{
host = gethostbyaddr( (char *)&now_ip,4,AF_INET);
/*
if (host == NULL) //如果返回NULL,则不存在,这里应该可以去掉这个判断,因为主调函数Get_Mac()已经判断了主机存活
{
InterlockedExchangeAdd((long *)&Threadnum,-1);
return ;
}
*/
}

DWORD WINAPI scan_lan(LPVOID lp) //扫描线程函数
{
int host_id = *(DWORD*)lp;

Get_Mac(host_id);

InterlockedExchangeAdd((long *)&Threadnum,-1);

return 0;

}

void usage(char *filename)
{
printf("\nusage : %s Network_Address\n",filename);
printf("\nIf your ip address is: 192.168.1.1 \n\nPlease input:");
printf("\t%s 192.168.1\n",filename);
exit(0);
}

void Display_Welcome()
{
printf("\n");
printf(" ===========================================================================\n");
printf(" = =\n");
printf(" = Welcome to using ip scaner =\n");


printf(" = Programing By okhelper =\n");
printf(" = QQ:274002432 =\n");
printf(" = 2008.5.8 =\n");
printf(" = =\n");
printf(" ===========================================================================\n");
}

void Display_Face()
{
printf("\n\t\t%2s局 域 网 内 存 活 主 机 列 表\n"," ");
printf(" -----------------------------------------\n");
printf("\n 计 算 机 名\t\tI P 地 址\t\tM A C 地 址\n\n");
}



[解决办法]
2个问题
for ( int i = 1; i <= 254; i++)
{
CreateThread(NULL,0,scan_lan, &i,0,NULL);

你这里传入线程的是i的地址,而i是一直在变化的,这就难保证线程是否正确得到i的值


printf("%10s\t\t%10s.%d\t\t%02X-%02X-%02X-%02X-%02X-%02X\n",host->h_name ,net_id,host_id,mac_addr[0],mac_addr[1],mac_addr[2],mac_addr[3],mac_addr[4],mac_addr[5]);
这里host->h_name 你有没有想过正确性?要是获取不到主机名怎么办?是不是应该判断一下

printf("%10s\t\t%10s.%d\t\t%02X-%02X-%02X-%02X-%02X-%02X\n",host == NULL ? " " : host->h_name ,net_id,host_id,mac_addr[0],mac_addr[1],mac_addr[2],mac_addr[3],mac_addr[4],mac_addr[5]);
[解决办法]
1
直接传i进去 CreateThread(NULL,0,scan_lan, (LPVOID)i,0,NULL);
线程函数中int host_id = (int)lp;

还有就是为什么开这么多线程呢?我觉得在一个线程里边循环比较好,还容易控制

2
我在为这里测试你的程序,host有为NULL的情况,直接就异常了

读书人网 >C语言

热点推荐