我自己写的扫描局域网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的情况,直接就异常了