因为使用gethostbyaddr 这个API有某些系统下不能正确获取远程计算机名。所以使用NetBios 获取计算机名。
windows 系统有一个小工具使用 nbtstat -a ip 可以获内网计算机名。
1、使用 Wireshark 2.0 抓取 nbtstat -a 发送的包数据
a) 设置过滤条件为udp 端口 137
捕获->选项 选中你的网卡 ->选择接口的捕获筛选器 输入 port 137 如下图
b) 点击开始 然后在 命令行 运行
C:\Users\John>nbtstat -a 192.168.17.135
然后就捕获到了发送接受的数据了。
c) 提取发送数据
选中发送的数据,右建->追踪流->UDP 流 如下图
设置 显示数据为 ->”C Arrays” 如下图
peer0_0 就是我们需要的数据包了。
源码如下:
// netbios.cpp : 定义控制台应用程序的入口点。 // // [12/8/2015 cnfreebsd@163.com ] #include "stdafx.h" #include <string> #include <atlconv.h> #include <stdio.h> #include <Winsock2.h> #pragma comment(lib, "ws2_32.lib") std::string trim_right(const std::string& str) { if (str.begin() == str.end()) { return str; } std::string t = str; std::string::iterator i; for (i = t.end() - 1; ;--i) { if (!isspace(*i)) { t.erase(i + 1, t.end()); break; } if (i == t.begin()) { t.clear(); break; } } return t; } int _tmain(int argc, _TCHAR* argv[]) { USES_CONVERSION; SOCKET hsock; WSADATA wsaData; if (WSAStartup(MAKEWORD(2,1),&wsaData)) { WSACleanup(); return 0; } struct sockaddr_in sockaddr; int len = sizeof(sockaddr); sockaddr.sin_family = AF_INET; sockaddr.sin_port = htons(137); sockaddr.sin_addr.s_addr = inet_addr(T2A(argv[1])); hsock = socket(AF_INET,SOCK_DGRAM,0); struct timeval tv_out; tv_out.tv_sec = 10 * 1000;//等待10秒 tv_out.tv_usec = 0; setsockopt(hsock,SOL_SOCKET,SO_RCVTIMEO, (const char*)&tv_out, sizeof(tv_out)); std::string strHostName; char cNBNS[] = { /* Packet 40 */ 0xf6, 0x45, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x43, 0x4b, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x00, 0x00, 0x21, 0x00, 0x01 }; if(sendto(hsock, (const char*)cNBNS, 50, 0, (struct sockaddr*)&sockaddr,len) != SOCKET_ERROR) { char buf[1024] = "\0"; if (recvfrom(hsock, buf, sizeof(buf), 0, (struct sockaddr*)&sockaddr, &len) != SOCKET_ERROR) { std::string strTemp,strHost; int nTemp = 0; int nNum = 0; bool bAdd = true; //NBTSTAT 前面的57个字节 for(int i = 57; i < _countof(buf); i++) { // 结束 if(buf[i] == 0xcc) break; if(buf[i] == 0x20) bAdd = false; if(bAdd) { char tmp[MAX_PATH] = {0}; sprintf(tmp, "%c", buf[i]); strTemp = tmp; if(buf[i]>=' ') { strHost+=strTemp; } } if((++nTemp)%18 == 0) { strHost = trim_right(strHost); if(nNum == 0 && strHost != "" ) { strHostName = strHost; nNum++; } } } } } printf("IP: %s 计算机名:%s", T2A(argv[1]), strHostName.c_str()); }
- 本文固定链接: http://www.mydoop.com/2015/12/c-获取计算机名(使用netbios)/
- 转载请注明: dnybz 于 我的站点 发表