windows获取wifi的bssid(mac地址)进行wifi定位

来源:互联网 发布:sip摄像机软件 编辑:程序博客网 时间:2024/06/06 08:37

wifi定位:顾名思义就是利用wifi来进行定位的功能。其原理是通过带有gps定位功能的设备接入wifi后,讲wifi的bssid信息连同gps定位结果同时上传到服务器,当有其他设备再次连接这个wifi时,就能大致的推断出他的位置。

在win8.1后已经提供接口可直接获取设备的经定位信息,当然xp、win7呢?显然不支持。由此我们就想到有没有办法让他们也能够定位呢?答案是肯定的!

一、首先你的计算机要支持wifi,不然就扯淡了。看看如何获取wifi的bssid吧。

#include <wlanapi.h>typedef std::string AString;typedef std::vector<AString> AStringVector;// Need to link with Wlanapi.lib and Ole32.lib#pragma comment(lib, "wlanapi.lib")#pragma comment(lib, "ole32.lib")#pragma comment(lib,"netapi32")AStringVector GetBSSIDs(){AStringVector vecBSSIDs;// Declare and initialize variables.HANDLE hClient = NULL;DWORD dwMaxClient = 2;      //    DWORD dwCurVersion = 0;DWORD dwResult = 0;DWORD dwRetVal = 0;int iRet = 0;WCHAR GuidString[39] = { 0 };unsigned int i, j, k;/* variables used for WlanEnumInterfaces  */PWLAN_INTERFACE_INFO_LIST pIfList = NULL;PWLAN_INTERFACE_INFO pIfInfo = NULL;PWLAN_AVAILABLE_NETWORK_LIST pBssList = NULL;PWLAN_AVAILABLE_NETWORK pBssEntry = NULL;int iRSSI = 0;dwResult = WlanOpenHandle(dwMaxClient, NULL, &dwCurVersion, &hClient);if (dwResult == ERROR_SUCCESS){dwResult = WlanEnumInterfaces(hClient, NULL, &pIfList);if (dwResult != ERROR_SUCCESS) {LOG("WlanEnumInterfaces failed with error: %u\n", dwResult);// You can use FormatMessage here to find out why the function failed}else {for (i = 0; i < (int)pIfList->dwNumberOfItems; i++) {pIfInfo = (WLAN_INTERFACE_INFO *)&pIfList->InterfaceInfo[i];dwResult = WlanGetAvailableNetworkList(hClient,&pIfInfo->InterfaceGuid, 0, NULL, &pBssList);if (dwResult != ERROR_SUCCESS) {LOG("WlanGetAvailableNetworkList failed with error: %u\n", dwResult);dwRetVal = 1;// You can use FormatMessage to find out why the function failed}else {for (j = 0; j < pBssList->dwNumberOfItems; j++){pBssEntry = (WLAN_AVAILABLE_NETWORK *)& pBssList->Network[j];PWLAN_BSS_LIST ppWlanBssList;DWORD dwResult2 = WlanGetNetworkBssList(hClient, &pIfInfo->InterfaceGuid,&pBssEntry->dot11Ssid,pBssEntry->dot11BssType,pBssEntry->bSecurityEnabled,NULL,&ppWlanBssList);if (dwResult2 == ERROR_SUCCESS){for (int z = 0; z < ppWlanBssList->dwNumberOfItems; z++){WLAN_BSS_ENTRY bssEntry = ppWlanBssList->wlanBssEntries[z];AString bssid = Printf("%02X:%02X:%02X:%02X:%02X:%02X",bssEntry.dot11Bssid[0],bssEntry.dot11Bssid[1],bssEntry.dot11Bssid[2],bssEntry.dot11Bssid[3],bssEntry.dot11Bssid[4],bssEntry.dot11Bssid[5]);vecBSSIDs.push_back(bssid);}}}}}}}else{LOG("WlanOpenHandle failed with error: %u\n", dwResult);// You can use FormatMessage here to find out why the function failed}if (pBssList != NULL) {WlanFreeMemory(pBssList);pBssList = NULL;}if (pIfList != NULL) {WlanFreeMemory(pIfList);pIfList = NULL;}return vecBSSIDs;}

二、看看如何使用这些bssid吧。

我们以百度的wifi定位接口为例,当然谷歌、新浪等等都有类似的接口,甚至还有收费的。

#include <json/json.h>#include <curl/curl.h>AString url = "http://apis.baidu.com/lbs_repository/wifi/query?coord=wgs84&mac=";size_t write_data(void* buffer, size_t size, size_t nmemb, void *stream){AString *fptr = (AString*)stream;fptr->append((char*)buffer);return size*nmemb;}void getGeoInfo(const AString &url, const AString &bssid,const AString &appkey){AString postUrl = url + bssid;CURL *curl;CURLcode res;AString *strRet = new AString;struct curl_slist *headers = NULL; /* init to NULL is important */headers = curl_slist_append(headers, AString("apikey: "+ m_strAppKey).c_str());curl = curl_easy_init();curl_easy_setopt(curl, CURLOPT_URL, postUrl.c_str());curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);curl_easy_setopt(curl, CURLOPT_WRITEDATA, strRet);curl_easy_setopt(curl, CURLOPT_HEADER, 1);res = curl_easy_perform(curl);curl_easy_cleanup(curl);if (res != CURLE_OK){switch (res){case CURLE_UNSUPPORTED_PROTOCOL:fprintf(stderr, "不支持的协议,由URL的头部指定\n");case CURLE_COULDNT_CONNECT:fprintf(stderr, "不能连接到remote主机或者代理\n");case CURLE_HTTP_RETURNED_ERROR:fprintf(stderr, "http返回错误\n");case CURLE_READ_ERROR:fprintf(stderr, "读本地文件错误\n");default:fprintf(stderr, "返回值:%d\n", res);}}AString strResult = *strRet;delete strRet;size_t end_index = strResult.find("\r\n\r\n");//所以也不需要计算偏移来提高搜索速度if (end_index != std::string::npos){size_t length = strResult.length();AString strBody = strResult.substr(end_index + 4, length - end_index - 4);AString strHeader = strResult.substr(0, end_index + 4);//正常HTTP头中 第9-11位为HTTP状态码size_t lenght = strHeader.length();int _http_code = -1;if (lenght >= 12){std::string http_code = strHeader.substr(9, 3);try{_http_code = atoi(http_code.c_str());}catch (...){_http_code = -1;}}if (_http_code == 200){Json::Reader reader;Json::Value root;if (reader.parse(strBody, root))  // reader将Json字符串解析到root,root将包含Json里所有子元素  {UInt32 errcode = root["errcode"].asUInt();UInt32 radius = atoi(root["radius"].asString().c_str());double lat = atof(root["lat"].asString().c_str());double lon = atof(root["lon"].asString().c_str());AString address = root["address"].asString();if (errcode == 0){//定位成功}}}}}

好了,到此为止基本上已经讲完了。wifi定位不能作为最终的结果,毕竟数据库可能不完整或者不实时,定位的结果存在偏差也是很正常的。我们一般还要采取其他方式进行混合定位,比如:基站+wifi+ip+gps等等。

再次希望对需要的人有帮助,谢谢。



1 0
原创粉丝点击