自动计算当前局域网IP段
多线程扫描
输出每个存活主机的IP和MAC地址,以及存活的总数(不带网卡厂商信息)
缺点:
自动获取区域网IP段 不可控IP 比如我扩大子网范围
遇到双网卡的情况下默认只扫描一个
///自动扫描局域网存活主机//优点:不用输入ip//缺点:如果遇到主机多IP只能扫描其中一个#include#include #include #pragma comment (lib,"ws2_32.lib") #pragma comment (lib,"iphlpapi.lib")// 线程参数结构体 struct CThreadParam{ UINT uIp; // 整数的ip地址 HANDLE hEventCopy; // 赋值参数的事件};CRITICAL_SECTION cs; // 打印时用到的临界区UINT uTotal = 0; // 输出一共存活的主机/// 用户扫描单个主机的线程函数DWORD WINAPI LanScan(LPVOID param) { HRESULT result; CThreadParam cParam; ULONG c[2] = {0},len=6; cParam = *(CThreadParam *)param; SetEvent(cParam.hEventCopy); // 这句关键 result = SendARP(htonl(cParam.uIp),NULL,c,&len); //发送ARP包 // 没有错误就输出 if(result == NO_ERROR) { UINT i; BYTE *g = (BYTE *)&c; in_addr target_addr; target_addr.S_un.S_addr=htonl((cParam.uIp)); if (len) { ::EnterCriticalSection(&cs); printf("host %s living, max address:", inet_ntoa(target_addr)); for (i = 0; i < (int) len; i++) { if (i == (len - 1)) { printf("%.2X\n", (int) g[i]); } else { printf("%.2X-", (int) g[i]); } } uTotal++; ::LeaveCriticalSection(&cs); } } return 0;}int main(){ // 初始化socket WSADATA data; WORD wVersion = MAKEWORD(2,2); WSAStartup(wVersion,&data); hostent *pLocalHost; HANDLE hEvent; // 获得本机IP结构 pLocalHost = ::gethostbyname(""); // 这样获得是网络字节序 ULONG ulIpAddress = (*(struct in_addr *)*(pLocalHost->h_addr_list)).S_un.S_addr; PIP_ADAPTER_INFO pAdapterInfo=NULL; ULONG ulLen=0; // 为适配器结构申请内存 ::GetAdaptersInfo(pAdapterInfo,&ulLen); pAdapterInfo=(PIP_ADAPTER_INFO)::GlobalAlloc(GPTR,ulLen); // 初始化线程里用到的参数 ::InitializeCriticalSection(&cs); hEvent = ::CreateEventW(NULL, FALSE, FALSE, NULL); CThreadParam cParam; //取得本地适配器结构信息 if(::GetAdaptersInfo(pAdapterInfo,&ulLen)==ERROR_SUCCESS) { while (pAdapterInfo!=NULL) { if (::inet_addr(pAdapterInfo->IpAddressList.IpAddress.String) == ulIpAddress) { // 这里要转换为主机字节序 ULONG ulIpMask = ntohl(::inet_addr(pAdapterInfo->IpAddressList.IpMask.String)); // 与获得网络号 ULONG ulNetName = ntohl(ulIpAddress) & ulIpMask; // 取非减2获得这个网段的主机数 UINT unNum = ~ulIpMask; UINT nNumofHost = unNum - 2; // 循环把主机的IP带入线程进行扫描 UINT i; HANDLE hThread; DWORD wThread; for (i = 0; i < nNumofHost; i++) { // 存的都是主机字节序 cParam.uIp = ulNetName + i + 1; cParam.hEventCopy = hEvent; hThread = CreateThread(NULL, 0, LanScan, (LPVOID)&cParam, 0, &wThread); ::WaitForSingleObject(hEvent, INFINITE); } break; } pAdapterInfo = pAdapterInfo->Next; } } // 休息5秒,等待线程执行结束 Sleep(5000); printf("\ntotal = %d\n", uTotal); return 0;}
VS2008下编译的,如果用vc6.0要加SDK才有相关的头文件。