關於iOS配置ipv6和ipv4地址不同時的處理辦法
當ipv6和ipv4地址不同時的處理:
-(void)getHost{
if ([DeviceInfo isIpv6]) {
return hostIpv6;
}
return hostIpv4;
}
-(void)getBaseUrl{
if ([DeviceInfo isIpv6]) {
return baseUrlIpv6;
}
return baseUrlIpv4;
}
具體的DeviceInfo類如下
DeviceInfo.h
#import <Foundation/Foundation.h>
@interface DeviceInfo : NSObject
+ (NSString *) OpenUDID;
+ (BOOL)isIpv6;
+ (NSString *)getIPAddress:(BOOL)preferIPv4;
@end
DeviceInfo.m
#import "YCX_DeviceInfo.h"
#import <AssetsLibrary/AssetsLibrary.h>
#import <MobileCoreServices/MobileCoreServices.h>
#import "SvUDIDTools.h"
#include <ifaddrs.h>
#include <arpa/inet.h>
#include <net/if.h>
#define IOS_CELLULAR @"pdp_ip0"
#define IOS_WIFI @"en0"
#define IOS_VPN @"utun0"
#define IP_ADDR_IPv4 @"ipv4"
#define IP_ADDR_IPv6 @"ipv6"
@implementation DeviceInfo
+ (BOOL)isIpv6
{
NSString *ipv6 = [self getIPAddress:NO ];
NSInteger count = [ipv6 countOccurencesOfString:@":"];
if (count >= 6) {
return YES;
}
return NO;
}
+ (NSString *)getIPAddress:(BOOL)preferIPv4
{
NSArray *searchArray = preferIPv4 ?
@[ IOS_VPN @"/" IP_ADDR_IPv4, IOS_VPN @"/" IP_ADDR_IPv6, IOS_WIFI @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6 ] :
@[ IOS_VPN @"/" IP_ADDR_IPv6, IOS_VPN @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv6, IOS_WIFI @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4 ] ;
NSDictionary *addresses = [self getIPAddresses];
__block NSString *address;
[searchArray enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop)
{
address = addresses[key];
if(address) *stop = YES;
} ];
return address ? address : @"0.0.0.0";
}
+ (NSDictionary *)getIPAddresses
{
NSMutableDictionary *addresses = [NSMutableDictionary dictionaryWithCapacity:8];
// retrieve the current interfaces - returns 0 on success
struct ifaddrs *interfaces;
if(!getifaddrs(&interfaces)) {
// Loop through linked list of interfaces
struct ifaddrs *interface;
for(interface=interfaces; interface; interface=interface->ifa_next) {
if(!(interface->ifa_flags & IFF_UP) /* || (interface->ifa_flags & IFF_LOOPBACK) */ ) {
continue; // deeply nested code harder to read
}
const struct sockaddr_in *addr = (const struct sockaddr_in*)interface->ifa_addr;
char addrBuf[ MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) ];
if(addr && (addr->sin_family==AF_INET || addr->sin_family==AF_INET6)) {
NSString *name = [NSString stringWithUTF8String:interface->ifa_name];
NSString *type;
if(addr->sin_family == AF_INET) {
if(inet_ntop(AF_INET, &addr->sin_addr, addrBuf, INET_ADDRSTRLEN)) {
type = IP_ADDR_IPv4;
}
} else {
const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*)interface->ifa_addr;
if(inet_ntop(AF_INET6, &addr6->sin6_addr, addrBuf, INET6_ADDRSTRLEN)) {
type = IP_ADDR_IPv6;
}
}
if(type) {
NSString *key = [NSString stringWithFormat:@"%@/%@", name, type];
addresses[key] = [NSString stringWithUTF8String:addrBuf];
}
}
}
// Free memory
freeifaddrs(interfaces);
}
return [addresses count] ? addresses : nil;
}
+ (NSString *) OpenUDID{
return [[UIDevice currentDevice].identifierForVendor UUIDString];
}
使用到的SvUDIDTools類方法設定如下:
#import <Foundation/Foundation.h>
@interface SvUDIDTools : NSObject
/*
* @brief obtain Unique Device Identity
*/
+ (NSString*)UDID;
@end
#import "SvUDIDTools.h"
#import <Security/Security.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_dl.h>
// replace the identity with your company's domain
static const char kKeychainUDIDItemIdentifier[] = "UUID";
static const char kKeyChainUDIDAccessGroup[] = "請設定你自己的";
@implementation SvUDIDTools
+ (NSString*)UDID
{
NSString *udid = [SvUDIDTools getUDIDFromKeyChain];
if (!udid) {
NSString *sysVersion = [UIDevice currentDevice].systemVersion;
CGFloat version = [sysVersion floatValue];
if (version >= 7.0) {
udid = [SvUDIDTools _UDID_iOS7];
}
else if (version >= 2.0) {
udid = [SvUDIDTools _UDID_iOS6];
}
[SvUDIDTools settUDIDToKeyChain:udid];
}
return udid;
}
/*
* iOS 6.0
* use wifi's mac address
*/
+ (NSString*)_UDID_iOS6
{
return [SvUDIDTools getMacAddress];
}
/*
* iOS 7.0
* Starting from iOS 7, the system always returns the value 02:00:00:00:00:00
* when you ask for the MAC address on any device.
* use identifierForVendor + keyChain
* make sure UDID consistency atfer app delete and reinstall
*/
+ (NSString*)_UDID_iOS7
{
return [[UIDevice currentDevice].identifierForVendor UUIDString];
}
#pragma mark -
#pragma mark Helper Method for Get Mac Address
// from http://stackoverflow.com/questions/677530/how-can-i-programmatically-get-the-mac-address-of-an-iphone
+ (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 = nil;
// 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);
if (msgBuffer) {
free(msgBuffer);
}
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;
}
#pragma mark -
#pragma mark Helper Method for make identityForVendor consistency
+ (NSString*)getUDIDFromKeyChain
{
NSMutableDictionary *dictForQuery = [[NSMutableDictionary alloc] init];
[dictForQuery setValue:(id)kSecClassGenericPassword forKey:(id)kSecClass];
// set Attr Description for query
[dictForQuery setValue:[NSString stringWithUTF8String:kKeychainUDIDItemIdentifier]
forKey:(NSString *)kSecAttrDescription];
// set Attr Identity for query
NSData *keychainItemID = [NSData dataWithBytes:kKeychainUDIDItemIdentifier
length:strlen(kKeychainUDIDItemIdentifier)];
[dictForQuery setObject:keychainItemID forKey:(id)kSecAttrGeneric];
// The keychain access group attribute determines if this item can be shared
// amongst multiple apps whose code signing entitlements contain the same keychain access group.
NSString *accessGroup = [NSString stringWithUTF8String:kKeyChainUDIDAccessGroup];
if (accessGroup != nil)
{
#if TARGET_IPHONE_SIMULATOR
// Ignore the access group if running on the iPhone simulator.
//
// Apps that are built for the simulator aren't signed, so there's no keychain access group
// for the simulator to check. This means that all apps can see all keychain items when run
// on the simulator.
//
// If a SecItem contains an access group attribute, SecItemAdd and SecItemUpdate on the
// simulator will return -25243 (errSecNoAccessForItem).
#else
[dictForQuery setObject:accessGroup forKey:(id)kSecAttrAccessGroup];
#endif
}
[dictForQuery setValue:(id)kCFBooleanTrue forKey:(id)kSecMatchCaseInsensitive];
[dictForQuery setValue:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
[dictForQuery setValue:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
OSStatus queryErr = noErr;
NSData *udidValue = nil;
NSString *udid = nil;
CFTypeRef typeRef = (__bridge CFTypeRef)udidValue;
queryErr = SecItemCopyMatching((CFDictionaryRef)dictForQuery, &typeRef);
NSMutableDictionary *dict = nil;
[dictForQuery setValue:(id)kCFBooleanTrue forKey:(id)kSecReturnAttributes];
CFTypeRef typeDict = (__bridge CFTypeRef)dict;
queryErr = SecItemCopyMatching((CFDictionaryRef)dictForQuery, &typeDict);
if (queryErr == errSecItemNotFound) {
NSLog(@"KeyChain Item: %@ not found!!!", [NSString stringWithUTF8String:kKeychainUDIDItemIdentifier]);
}
else if (queryErr != errSecSuccess) {
NSLog(@"KeyChain Item query Error!!! Error code:%d", queryErr);
}
if (queryErr == errSecSuccess) {
NSLog(@"KeyChain Item: %@", udidValue);
if (udidValue) {
udid = [NSString stringWithUTF8String:udidValue.bytes];
}
}
return udid;
}
+ (BOOL)settUDIDToKeyChain:(NSString*)udid
{
NSMutableDictionary *dictForAdd = [[NSMutableDictionary alloc] init];
[dictForAdd setValue:(id)kSecClassGenericPassword forKey:(id)kSecClass];
[dictForAdd setValue:[NSString stringWithUTF8String:kKeychainUDIDItemIdentifier] forKey:(NSString *)kSecAttrDescription];
[dictForAdd setValue:@"UUID" forKey:(id)kSecAttrGeneric];
// Default attributes for keychain item.
[dictForAdd setObject:@"" forKey:(id)kSecAttrAccount];
[dictForAdd setObject:@"" forKey:(id)kSecAttrLabel];
// The keychain access group attribute determines if this item can be shared
// amongst multiple apps whose code signing entitlements contain the same keychain access group.
NSString *accessGroup = [NSString stringWithUTF8String:kKeyChainUDIDAccessGroup];
if (accessGroup != nil)
{
#if TARGET_IPHONE_SIMULATOR
// Ignore the access group if running on the iPhone simulator.
//
// Apps that are built for the simulator aren't signed, so there's no keychain access group
// for the simulator to check. This means that all apps can see all keychain items when run
// on the simulator.
//
// If a SecItem contains an access group attribute, SecItemAdd and SecItemUpdate on the
// simulator will return -25243 (errSecNoAccessForItem).
#else
[dictForAdd setObject:accessGroup forKey:(id)kSecAttrAccessGroup];
#endif
}
const char *udidStr = [udid UTF8String];
NSData *keyChainItemValue = [NSData dataWithBytes:udidStr length:strlen(udidStr)];
[dictForAdd setValue:keyChainItemValue forKey:(id)kSecValueData];
OSStatus writeErr = noErr;
if ([SvUDIDTools getUDIDFromKeyChain]) { // there is item in keychain
[SvUDIDTools updateUDIDInKeyChain:udid];
return YES;
}
else { // add item to keychain
writeErr = SecItemAdd((CFDictionaryRef)dictForAdd, NULL);
if (writeErr != errSecSuccess) {
NSLog(@"Add KeyChain Item Error!!! Error Code:%d", writeErr);
return NO;
}
else {
NSLog(@"Add KeyChain Item Success!!!");
return YES;
}
}
return NO;
}
+ (BOOL)removeUDIDFromKeyChain
{
NSMutableDictionary *dictToDelete = [[NSMutableDictionary alloc] init];
[dictToDelete setValue:(id)kSecClassGenericPassword forKey:(id)kSecClass];
NSData *keyChainItemID = [NSData dataWithBytes:kKeychainUDIDItemIdentifier length:strlen(kKeychainUDIDItemIdentifier)];
[dictToDelete setValue:keyChainItemID forKey:(id)kSecAttrGeneric];
OSStatus deleteErr = noErr;
deleteErr = SecItemDelete((CFDictionaryRef)dictToDelete);
if (deleteErr != errSecSuccess) {
NSLog(@"delete UUID from KeyChain Error!!! Error code:%d", deleteErr);
return NO;
}
else {
NSLog(@"delete success!!!");
}
return YES;
}
+ (BOOL)updateUDIDInKeyChain:(NSString*)newUDID
{
NSMutableDictionary *dictForQuery = [[NSMutableDictionary alloc] init];
[dictForQuery setValue:(id)kSecClassGenericPassword forKey:(id)kSecClass];
NSData *keychainItemID = [NSData dataWithBytes:kKeychainUDIDItemIdentifier
length:strlen(kKeychainUDIDItemIdentifier)];
[dictForQuery setValue:keychainItemID forKey:(id)kSecAttrGeneric];
[dictForQuery setValue:(id)kCFBooleanTrue forKey:(id)kSecMatchCaseInsensitive];
[dictForQuery setValue:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
[dictForQuery setValue:(id)kCFBooleanTrue forKey:(id)kSecReturnAttributes];
NSDictionary *queryResult = nil;
CFTypeRef typeQuery = (__bridge CFTypeRef)queryResult;
SecItemCopyMatching((CFDictionaryRef)dictForQuery, &typeQuery);
if (queryResult) {
NSMutableDictionary *dictForUpdate = [[NSMutableDictionary alloc] init];
[dictForUpdate setValue:[NSString stringWithUTF8String:kKeychainUDIDItemIdentifier] forKey:(NSString *)kSecAttrDescription];
[dictForUpdate setValue:keychainItemID forKey:(id)kSecAttrGeneric];
const char *udidStr = [newUDID UTF8String];
NSData *keyChainItemValue = [NSData dataWithBytes:udidStr length:strlen(udidStr)];
[dictForUpdate setValue:keyChainItemValue forKey:(id)kSecValueData];
OSStatus updateErr = noErr;
// First we need the attributes from the Keychain.
NSMutableDictionary *updateItem = [NSMutableDictionary dictionaryWithDictionary:queryResult];
// Second we need to add the appropriate search key/values.
// set kSecClass is Very important
[updateItem setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
updateErr = SecItemUpdate((CFDictionaryRef)updateItem, (CFDictionaryRef)dictForUpdate);
if (updateErr != errSecSuccess) {
NSLog(@"Update KeyChain Item Error!!! Error Code:%d", updateErr);
return NO;
}
else {
NSLog(@"Update KeyChain Item Success!!!");
return YES;
}
}
return NO;
}
相關推薦
關於iOS配置ipv6和ipv4地址不同時的處理辦法
當ipv6和ipv4地址不同時的處理: -(void)getHost{ if ([DeviceInfo isIpv6]) { return hostIpv6; } return hostIpv4; } -(void)get
HAproxy配置IPv6和IPv4的互相代理實驗
這裡我們使用簡單的 httpd 服務進行測試。 實驗環境 序號 IPv4地址 IPv6地址 1 10.144.91.124 fd88:5110:a240::886:
ubuntu下100%成功安裝torch,同時配置cuda和cudnn(不成功,則成仁)
總說這些更新不影響主體。所有更新附加在文章最後。 第一次更新: 內容:新增一些Torch7常用庫的安裝,時間:2017.3.20 第二次更新:內容:某些torch庫無法線上安裝,轉成離線安裝的方法,時間:2017.3.31 第三次更新:內容:針對安裝”cutorch”時出錯的問
用getaddrinfo()函式,通過主機名獲得ipv6和ipv4的地址
111111111111111 using the function "getaddrinfo()" to get the IP address from the hostname you provided; actually , the "getadrinfo()" function can get
第11章 拾遺4:IPv6和IPv4共存技術(1)_雙棧技術和6to4隧道技術
說明 images 測試結果 ges conf alt style dns服務 數據 6. IPv6和IPv4共存技術 6.1 雙棧技術 (1)雙協議主機的協議結構 (2)雙協議棧示意圖 ①雙協議主機在通信時首先通過支持雙協議的DNS服務器查詢與目的主機名對應的
第11章 拾遺5:IPv6和IPv4共存技術(3)_NAT-PT技術【全書完】
cas 不知道 路由 共存 同時 種類型 並且 修改 添加 6.4 NAT-PT (1)NAT-PT和NAT的差別 ①NAT-PT(附帶協議轉換的網絡地址轉換)技術秉承NAT技術的思想,但在原理方面大有不同。 ②NAT-PT和NAT本質的區別在於應用場合的不同。
第11章 拾遺5:IPv6和IPv4共存技術(2)_ISATAP隧道技術
6.3 ISATAP隧道技術 (1)基本概念 ①在一個IPv4網路中主機與路由器之間建立一條ISATAP隧道,以便讓該主機可以訪問IPv6網路中的資源。 ②條件:IPv4中的PC主機需要支援IPv4和IPv6雙棧協議,然後需要一臺支援ISATAP的路由器。該路由器可以在網路
第11章 拾遺5:IPv6和IPv4共存技術(1)_雙棧技術和6to4隧道技術
6. IPv6和IPv4共存技術 6.1 雙棧技術 (1)雙協議主機的協議結構 (2)雙協議棧示意圖 ①雙協議主機在通訊時首先通過支援雙協議的DNS伺服器查詢與目的主機名對應的IP地址。 ②再根據指定的IPv6或IPv4地址開始通訊。 ③Win2008
8.解析主機名對應的別名和IPv4地址
使用gethostbyname解析主機名對應的別名和IPv4地址 #include <netdb.h> #include <stdio.h> #include <net
centos7配置hostname和ip地址
主機名 退出 lur 主機 queue system def emc running 一、修改hostname 1、查看當前hostname [root@localhost~]# hostnamelocalhost 2、配置新主機名 [root@localhost~]# h
IPv6和IPv4基本頭部格式
原帖:http://book.51cto.com/art/201204/329740.htm 根據IPv4報文中存在的問題,IPv6報文頭格式與IPv4相比進行了一些改動。IPv6頭部結構遵循以下新規則: 基本頭部的固定長度:IPv6的基本報文頭長度固定為40位元組
ipv6和ipv4(1)
20174年7月5日 參考資料: 《Linux高效能伺服器程式設計》 linux-2.6.32原始碼 《TCP/IP詳解》(卷一) 網路程式設計最重要的一個環節就是要理清TCP/IP傳輸協議棧。而協議棧的學習自然的少不了最關鍵的一個環節就是
IP地址和廣播地址不在一個網段內時根據IP地址和子網掩碼計算廣播地址
看TCP/IP詳解 卷1這部大作的時候,看到裡面計算廣播地址的方法,就在自己的機器 上測試了一下,結果遇到了一個小困難:我的機器上IP地址和廣播地址不在一個網段: 廣播地址就是把IP地址中主機號的那幾位設定為1,可是這裡看起來確實都設定為1了(廣播地址的最後一段為255)
mybatis學習筆記(3)—資料庫和bean名稱不一樣處理方案
之前寫的mybatis物件的bean物件和資料庫的物件名稱是對應的,然而再實際開發的過程有很多不一一對應的情況。就需要解決。 bean物件: package com.test.bean; /* * javabean 物件 */ public class order { pr
Docker Tomcat應用日誌時間和容器時間不一致解決辦法
Docker 宿主機、容器、Tomcat應用日誌時間不一致解決辦法 說明: 1.在docker容器和系統時間不一致是因為docker容器的原生時區為0時區,而國內系統為東八區。 2.還有容器中執行的java應用打出的日誌時間和通過date -R
iOS 子檢視超出父檢視不響應解決辦法
父檢視中重寫該方法 Objective-C - (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event { UIView * view = [super hitTe
hexo categories和tags頁面不顯示解決辦法
方法一: scaffolds/draft.md --- title: {{ title }} tags: {{ tags }} --- scaffolds/post.md --- title
機器學習中樣本不平衡處理辦法
在機器學習任務中,我們經常會遇到這種困擾:資料不平衡問題。比如在廣告點選預估、反欺詐、風控裡面。 資料不平衡問題主要存在於有監督機器學習任務中。當遇到不平衡資料時,以總體分類準確率為學習目標的傳統分類演算法會過多地關注多數類,從而使得少數類樣本的分類效能下降。絕大
centos配置ipv6地址
linux 網站 網卡 賬號 default 首先打開網站註冊一個賬號:http://www.tunnelbroker.net創建一個ipv6的地址:首先打開linux對ipv6的支持:#vi /etc/sysconfig/network NETWORKING_IPV6=yes IPV6_
Cisco思科IOS配置控制臺Console口和遠程虛擬終端以及enable使能登錄密碼
cisco 遠程登錄 配置密碼 1、設置控制臺Console口密碼Router(config)#line console 0 #進入控制臺口Router(config-line)#login #允許口令登錄Router(config-line)#password xxx #登錄口令xx