Làm thế nào để lập trình lấy địa chỉ MAC và địa chỉ IP của iPhone?
02:00:00:00:00:00
khi bạn yêu cầu địa chỉ MAC trên bất kỳ thiết bị nào. Kiểm tra câu trả lời của tôi dưới đây.
Làm thế nào để lập trình lấy địa chỉ MAC và địa chỉ IP của iPhone?
02:00:00:00:00:00
khi bạn yêu cầu địa chỉ MAC trên bất kỳ thiết bị nào. Kiểm tra câu trả lời của tôi dưới đây.
Câu trả lời:
LƯU Ý Kể từ iOS7, bạn không còn có thể truy xuất địa chỉ MAC của thiết bị. Một giá trị cố định sẽ được trả về thay vì MAC thực tế
Một cái gì đó tôi tình cờ thấy một lúc trước. Ban đầu từ đây tôi đã sửa đổi nó một chút và dọn dẹp mọi thứ.
Và để sử dụng nó
InitAddresses();
GetIPAddresses();
GetHWAddresses();
int i;
NSString *deviceIP = nil;
for (i=0; i<MAXADDRS; ++i)
{
static unsigned long localHost = 0x7F000001; // 127.0.0.1
unsigned long theAddr;
theAddr = ip_addrs[i];
if (theAddr == 0) break;
if (theAddr == localHost) continue;
NSLog(@"Name: %s MAC: %s IP: %s\n", if_names[i], hw_addrs[i], ip_names[i]);
//decided what adapter you want details for
if (strncmp(if_names[i], "en", 2) == 0)
{
NSLog(@"Adapter en has a IP of %s", ip_names[i]);
}
}
Tên bộ điều hợp khác nhau tùy thuộc vào trình giả lập / thiết bị cũng như wifi hoặc di động trên thiết bị.
ether_ntoa
cảnh báo, hãy xem: stackoverflow.com/a/13412265/88597
Cập nhật: điều này sẽ không hoạt động trên iOS 7. Bạn nên sử dụng ASIdentifierManager .
Giải pháp sạch hơn trên trang web MobileDeveloperTips:
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_dl.h>
...
- (NSString *)getMacAddress
{
int mgmtInfoBase[6];
char *msgBuffer = NULL;
size_t length;
unsigned char macAddress[6];
struct if_msghdr *interfaceMsgStruct;
struct sockaddr_dl *socketStruct;
NSString *errorFlag = NULL;
// Setup the management Information Base (mib)
mgmtInfoBase[0] = CTL_NET; // Request network subsystem
mgmtInfoBase[1] = AF_ROUTE; // Routing table info
mgmtInfoBase[2] = 0;
mgmtInfoBase[3] = AF_LINK; // Request link layer information
mgmtInfoBase[4] = NET_RT_IFLIST; // Request all configured interfaces
// With all configured interfaces requested, get handle index
if ((mgmtInfoBase[5] = if_nametoindex("en0")) == 0)
errorFlag = @"if_nametoindex failure";
else
{
// Get the size of the data available (store in len)
if (sysctl(mgmtInfoBase, 6, NULL, &length, NULL, 0) < 0)
errorFlag = @"sysctl mgmtInfoBase failure";
else
{
// Alloc memory based on above call
if ((msgBuffer = malloc(length)) == NULL)
errorFlag = @"buffer allocation failure";
else
{
// Get system information, store in buffer
if (sysctl(mgmtInfoBase, 6, msgBuffer, &length, NULL, 0) < 0)
errorFlag = @"sysctl msgBuffer failure";
}
}
}
// Befor going any further...
if (errorFlag != NULL)
{
NSLog(@"Error: %@", errorFlag);
return errorFlag;
}
// Map msgbuffer to interface message structure
interfaceMsgStruct = (struct if_msghdr *) msgBuffer;
// Map to link-level socket structure
socketStruct = (struct sockaddr_dl *) (interfaceMsgStruct + 1);
// Copy link layer address data in socket structure to an array
memcpy(&macAddress, socketStruct->sdl_data + socketStruct->sdl_nlen, 6);
// Read from char array into a string object, into traditional Mac address format
NSString *macAddressString = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X",
macAddress[0], macAddress[1], macAddress[2],
macAddress[3], macAddress[4], macAddress[5]];
NSLog(@"Mac Address: %@", macAddressString);
// Release the buffer memory
free(msgBuffer);
return macAddressString;
}
IdentifierManager
02:00:00:00:00:00
như một biện pháp phòng ngừa quyền riêng tư của Apple.
Tôi muốn một cái gì đó trả về địa chỉ bất kể có bật wifi hay không, vì vậy giải pháp được chọn không phù hợp với tôi. Tôi đã sử dụng một cuộc gọi khác mà tôi tìm thấy trên một số diễn đàn sau khi điều chỉnh. Tôi đã kết thúc với những điều sau đây (xin lỗi C gỉ của tôi):
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <net/if_dl.h>
#include <ifaddrs.h>
char* getMacAddress(char* macAddress, char* ifName) {
int success;
struct ifaddrs * addrs;
struct ifaddrs * cursor;
const struct sockaddr_dl * dlAddr;
const unsigned char* base;
int i;
success = getifaddrs(&addrs) == 0;
if (success) {
cursor = addrs;
while (cursor != 0) {
if ( (cursor->ifa_addr->sa_family == AF_LINK)
&& (((const struct sockaddr_dl *) cursor->ifa_addr)->sdl_type == IFT_ETHER) && strcmp(ifName, cursor->ifa_name)==0 ) {
dlAddr = (const struct sockaddr_dl *) cursor->ifa_addr;
base = (const unsigned char*) &dlAddr->sdl_data[dlAddr->sdl_nlen];
strcpy(macAddress, "");
for (i = 0; i < dlAddr->sdl_alen; i++) {
if (i != 0) {
strcat(macAddress, ":");
}
char partialAddr[3];
sprintf(partialAddr, "%02X", base[i]);
strcat(macAddress, partialAddr);
}
}
cursor = cursor->ifa_next;
}
freeifaddrs(addrs);
}
return macAddress;
}
Và sau đó tôi sẽ gọi nó là yêu cầu en0 , như sau:
char* macAddressString= (char*)malloc(18);
NSString* macAddress= [[NSString alloc] initWithCString:getMacAddress(macAddressString, "en0")
encoding:NSMacOSRomanStringEncoding];
free(macAddressString);
Bắt đầu từ iOS 7, hệ thống luôn trả về giá trị 02:00:00:00:00:00
khi bạn yêu cầu địa chỉ MAC trên bất kỳ thiết bị nào.
Trong iOS 7 trở lên, nếu bạn hỏi địa chỉ MAC của thiết bị iOS, hệ thống sẽ trả về giá trị 02: 00: 00: 00: 00: 00. Nếu bạn cần xác định thiết bị, thay vào đó, hãy sử dụng thuộc tính định danhForVendor của UIDevice. (Các ứng dụng cần một mã định danh cho mục đích quảng cáo của riêng họ nên xem xét sử dụng thuộc tính AdvertisingIdentifier của ASIdentifierManager.) "
Tham khảo: phát hành
Có nhiều giải pháp khác nhau về vấn đề này, nhưng tôi không thể tìm thấy toàn bộ. Vì vậy, tôi đã thực hiện giải pháp của riêng mình cho:
Cách sử dụng:
NICInfoSummary* summary = [[[NICInfoSummary alloc] init] autorelease];
// en0 is for WiFi
NICInfo* wifi_info = [summary findNICInfo:@"en0"];
// you can get mac address in 'XX-XX-XX-XX-XX-XX' form
NSString* mac_address = [wifi_info getMacAddressWithSeparator:@"-"];
// ip can be multiple
if(wifi_info.nicIPInfos.count > 0)
{
NICIPInfo* ip_info = [wifi_info.nicIPInfos objectAtIndex:0];
NSString* ip = ip_info.ip;
NSString* netmask = ip_info.netmask;
NSString* broadcast_ip = ip_info.broadcastIP;
}
else
{
NSLog(@"WiFi not connected!");
}
Đây có vẻ là một giải pháp khá sạch: UIDevice BIdentifier
// Return the local MAC addy
// Courtesy of FreeBSD hackers email list
// Accidentally munged during previous update. Fixed thanks to erica sadun & mlamb.
- (NSString *) macaddress{
int mib[6];
size_t len;
char *buf;
unsigned char *ptr;
struct if_msghdr *ifm;
struct sockaddr_dl *sdl;
mib[0] = CTL_NET;
mib[1] = AF_ROUTE;
mib[2] = 0;
mib[3] = AF_LINK;
mib[4] = NET_RT_IFLIST;
if ((mib[5] = if_nametoindex("en0")) == 0) {
printf("Error: if_nametoindex error\n");
return NULL;
}
if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
printf("Error: sysctl, take 1\n");
return NULL;
}
if ((buf = malloc(len)) == NULL) {
printf("Could not allocate memory. error!\n");
return NULL;
}
if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
printf("Error: sysctl, take 2");
free(buf);
return NULL;
}
ifm = (struct if_msghdr *)buf;
sdl = (struct sockaddr_dl *)(ifm + 1);
ptr = (unsigned char *)LLADDR(sdl);
NSString *outstring = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X",
*ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)];
free(buf);
return outstring;
}
Bây giờ các thiết bị iOS 7 - luôn trả về địa chỉ MAC là 02: 00: 00: 00: 00: 00.
Vì vậy, sử dụng tốt hơn [UIDevice định danhForVendor].
tốt hơn hết là gọi phương thức này để lấy khóa duy nhất của ứng dụng
Danh mục sẽ phù hợp hơn
nhập "UIDevice + Định danh.h"
- (NSString *) identifierForVendor1
{
if ([[UIDevice currentDevice] respondsToSelector:@selector(identifierForVendor)]) {
return [[[UIDevice currentDevice] identifierForVendor] UUIDString];
}
return @"";
}
Bây giờ gọi phương thức trên để có được địa chỉ duy nhất
NSString *like_UDID=[NSString stringWithFormat:@"%@",
[[UIDevice currentDevice] identifierForVendor1]];
NSLog(@"%@",like_UDID);
@Grantland "Giải pháp khá sạch" này trông tương tự như cải tiến của riêng tôi đối với giải pháp iPhoneDeveloperTips.
Bạn có thể xem bước của tôi ở đây: https://gist.github.com/1409855/
/* Original source code courtesy John from iOSDeveloperTips.com */
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_dl.h>
+ (NSString *)getMacAddress
{
int mgmtInfoBase[6];
char *msgBuffer = NULL;
NSString *errorFlag = NULL;
size_t length;
// Setup the management Information Base (mib)
mgmtInfoBase[0] = CTL_NET; // Request network subsystem
mgmtInfoBase[1] = AF_ROUTE; // Routing table info
mgmtInfoBase[2] = 0;
mgmtInfoBase[3] = AF_LINK; // Request link layer information
mgmtInfoBase[4] = NET_RT_IFLIST; // Request all configured interfaces
// With all configured interfaces requested, get handle index
if ((mgmtInfoBase[5] = if_nametoindex("en0")) == 0)
errorFlag = @"if_nametoindex failure";
// Get the size of the data available (store in len)
else if (sysctl(mgmtInfoBase, 6, NULL, &length, NULL, 0) < 0)
errorFlag = @"sysctl mgmtInfoBase failure";
// Alloc memory based on above call
else if ((msgBuffer = malloc(length)) == NULL)
errorFlag = @"buffer allocation failure";
// Get system information, store in buffer
else if (sysctl(mgmtInfoBase, 6, msgBuffer, &length, NULL, 0) < 0)
{
free(msgBuffer);
errorFlag = @"sysctl msgBuffer failure";
}
else
{
// Map msgbuffer to interface message structure
struct if_msghdr *interfaceMsgStruct = (struct if_msghdr *) msgBuffer;
// Map to link-level socket structure
struct sockaddr_dl *socketStruct = (struct sockaddr_dl *) (interfaceMsgStruct + 1);
// Copy link layer address data in socket structure to an array
unsigned char macAddress[6];
memcpy(&macAddress, socketStruct->sdl_data + socketStruct->sdl_nlen, 6);
// Read from char array into a string object, into traditional Mac address format
NSString *macAddressString = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X",
macAddress[0], macAddress[1], macAddress[2], macAddress[3], macAddress[4], macAddress[5]];
NSLog(@"Mac Address: %@", macAddressString);
// Release the buffer memory
free(msgBuffer);
return macAddressString;
}
// Error...
NSLog(@"Error: %@", errorFlag);
return nil;
}
Không thể thực hiện được nữa trên các thiết bị chạy iOS 7.0 trở lên, do đó không có sẵn địa chỉ MAC trong Swift.
Như Apple đã nêu:
Trong iOS 7 trở lên, nếu bạn hỏi địa chỉ MAC của thiết bị iOS, hệ thống sẽ trả về giá trị 02: 00: 00: 00: 00: 00. Nếu bạn cần xác định thiết bị, thay vào đó, hãy sử dụng thuộc tính định danhForVendor của UIDevice. (Các ứng dụng cần một mã định danh cho mục đích quảng cáo của riêng họ nên xem xét sử dụng thuộc tính AdvertisingIdentifier của ASIdentifierManager.)
#import <sys/socket.h>
#import <net/if_dl.h>
#import <ifaddrs.h>
#import <sys/xattr.h>
#define IFT_ETHER 0x6
...
- (NSString*)macAddress
{
NSString* result = nil;
char* macAddressString = (char*)malloc(18);
if (macAddressString != NULL)
{
strcpy(macAddressString, "");
struct ifaddrs* addrs = NULL;
struct ifaddrs* cursor;
if (getifaddrs(&addrs) == 0)
{
cursor = addrs;
while (cursor != NULL)
{
if ((cursor->ifa_addr->sa_family == AF_LINK) && (((const struct sockaddr_dl*)cursor->ifa_addr)->sdl_type == IFT_ETHER) && strcmp("en0", cursor->ifa_name) == 0)
{
const struct sockaddr_dl* dlAddr = (const struct sockaddr_dl*) cursor->ifa_addr;
const unsigned char* base = (const unsigned char*)&dlAddr->sdl_data[dlAddr->sdl_nlen];
for (NSInteger index = 0; index < dlAddr->sdl_alen; index++)
{
char partialAddr[3];
sprintf(partialAddr, "%02X", base[index]);
strcat(macAddressString, partialAddr);
}
}
cursor = cursor->ifa_next;
}
}
result = [[[NSString alloc] initWithUTF8String:macAddressString] autorelease];
free(macAddressString);
}
return result;
}
Để tạo uniqueString dựa trên số nhận dạng duy nhất của thiết bị trong iOS 6:
#import <AdSupport/ASIdentifierManager.h>
NSString *uniqueString = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
NSLog(@"uniqueString: %@", uniqueString);
Rất nhiều câu hỏi này chỉ giải quyết địa chỉ Mac. Nếu bạn cũng yêu cầu địa chỉ IP tôi vừa viết này, có thể cần một số công việc nhưng dường như hoạt động tốt trên máy của tôi ...
- (NSString *)getLocalIPAddress
{
NSArray *ipAddresses = [[NSHost currentHost] addresses];
NSArray *sortedIPAddresses = [ipAddresses sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
numberFormatter.allowsFloats = NO;
for (NSString *potentialIPAddress in sortedIPAddresses)
{
if ([potentialIPAddress isEqualToString:@"127.0.0.1"]) {
continue;
}
NSArray *ipParts = [potentialIPAddress componentsSeparatedByString:@"."];
BOOL isMatch = YES;
for (NSString *ipPart in ipParts) {
if (![numberFormatter numberFromString:ipPart]) {
isMatch = NO;
break;
}
}
if (isMatch) {
return potentialIPAddress;
}
}
// No IP found
return @"?.?.?.?";
}