小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

iOS開(kāi)發(fā)中WiFi相關(guān)功能總結(jié)

 Rdxer館 2016-07-15

1983664_907572.jpg

投稿文章,作者:Haley_Wong(簡(jiǎn)書(shū)

查漏補(bǔ)缺集是自己曾經(jīng)做過(guò)相關(guān)的功能,但是重做相關(guān)功能或者重新看到相關(guān)功能的實(shí)現(xiàn),感覺(jué)理解上更深刻。這一類的文章集中記錄在查漏補(bǔ)缺集。

iOS 開(kāi)發(fā)中難免會(huì)遇到很多與網(wǎng)絡(luò)方面的判斷,這里做個(gè)匯總,大多可能是與WiFi相關(guān)的。

1.Ping域名、Ping某IP

有時(shí)候可能會(huì)遇到ping 某個(gè)域名或者ip通不通,再做下一步操作。這里的ping與傳統(tǒng)的做get或者post請(qǐng)求還是有很大區(qū)別的。比如我們連接了某個(gè)WiFi,測(cè)試ping www.baidu.com,如果能ping 通,基本可以斷定可以上網(wǎng)了,但是如果我們做了一個(gè)get 請(qǐng)求(url 是www.baidu.com),路由器可能重定向這個(gè)WiFi內(nèi)的某網(wǎng)頁(yè)了,依然沒(méi)有錯(cuò)誤返回,就會(huì)誤認(rèn)為可以正常上網(wǎng)。

這里有關(guān)于ping命令的詳細(xì)解釋:百度百科Ping

iOS中想要ping域名或者ip,蘋(píng)果提供了一個(gè)官方例子SimplePing

在例子中,有一個(gè)蘋(píng)果已經(jīng)封裝過(guò)的類【SimplePing.h】和【SimplePing.m】

使用起來(lái)也相當(dāng)?shù)暮?jiǎn)單:

首先創(chuàng)建一個(gè)Ping對(duì)象:

1
2
3
4
5
 SimplePing *pinger = [[SimplePing alloc] initWithHostName:self.hostName];
 self.pinger = pinger;
 pinger.delegate = self;
 pinger.addressStyle = SimplePingAddressStyleICMPv4;
 [pinger start];

然后在start成功的代理方法中,發(fā)送數(shù)據(jù)報(bào)文:

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
 *  start成功,也就是準(zhǔn)備工作做完后的回調(diào)
 */
- (void)simplePing:(SimplePing *)pinger didStartWithAddress:(NSData *)address
{
    // 發(fā)送測(cè)試報(bào)文數(shù)據(jù)
    [self.pinger sendPingWithData:nil];
}
- (void)simplePing:(SimplePing *)pinger didFailWithError:(NSError *)error
{
    NSLog(@"didFailWithError");
    [self.pinger stop];
}

其他幾個(gè)代理方法也非常簡(jiǎn)單,就簡(jiǎn)單記錄一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 發(fā)送測(cè)試報(bào)文成功的回調(diào)方法
- (void)simplePing:(SimplePing *)pinger didSendPacket:(NSData *)packet sequenceNumber:(uint16_t)sequenceNumber
{
    NSLog(@"#%u sent", sequenceNumber);
}
//發(fā)送測(cè)試報(bào)文失敗的回調(diào)方法
- (void)simplePing:(SimplePing *)pinger didFailToSendPacket:(NSData *)packet sequenceNumber:(uint16_t)sequenceNumber error:(NSError *)error
{
    NSLog(@"#%u send failed: %@", sequenceNumber, error);
}
// 接收到ping的地址所返回的數(shù)據(jù)報(bào)文回調(diào)方法
- (void)simplePing:(SimplePing *)pinger didReceivePingResponsePacket:(NSData *)packet sequenceNumber:(uint16_t)sequenceNumber
{
    NSLog(@"#%u received, size=%zu", sequenceNumber, packet.length);
}
- (void)simplePing:(SimplePing *)pinger didReceiveUnexpectedPacket:(NSData *)packet
{
    NSLog(@"#%s",__func__);
}

注意點(diǎn):

iOS 中 ping失敗后(即發(fā)送測(cè)試報(bào)文成功后,一直沒(méi)后收到響應(yīng)的報(bào)文),不會(huì)有任何回調(diào)方法告知我們。而一般ping 一次的結(jié)果也不太準(zhǔn)確,ping 花費(fèi)的時(shí)間也非常短,所以我們一般會(huì)ping多次,發(fā)送一次ping 測(cè)試報(bào)文0.5s后檢測(cè)一下這一次ping是否已經(jīng)收到響應(yīng)。0.5s后檢測(cè)時(shí),如果已經(jīng)收到響應(yīng),則可以ping 通;如果沒(méi)有收到響應(yīng),則視為超時(shí)。

做法也有很多種,可以用NSTimer或者 {- (void)performSelector: withObject:afterDelay:}

這里有一個(gè)別人寫(xiě)的工程:https://github.com/lovesunstar/STPingTest

727768-ff8ab7124905812e.jpg

PingTest效果圖

727768-6d4c781945dd1334.jpg

終端ping效果圖

2.獲取WiFi信息

以前物聯(lián)網(wǎng)剛火的時(shí)候,出現(xiàn)過(guò)很多一體式無(wú)線路由,所以App里難免會(huì)遇到要判斷當(dāng)前所連接的WiFi,以及獲取WiFi信息的功能。13年的時(shí)候查過(guò)一些關(guān)于WiFi的方法,后面漸漸都忘記了。慚愧?。?!

需要添加SystemConfiguration.framework 并在當(dāng)前類中添加代碼#import

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//獲取WiFi 信息,返回的字典中包含了WiFi的名稱、路由器的Mac地址、還有一個(gè)Data(轉(zhuǎn)換成字符串打印出來(lái)是wifi名稱)
- (NSDictionary *)fetchSSIDInfo {
    NSArray *ifs = (__bridge_transfer NSArray *)CNCopySupportedInterfaces();
    if (!ifs) {
        return nil;
    }
    NSDictionary *info = nil;
    for (NSString *ifnam in ifs) {
        info = (__bridge_transfer NSDictionary *)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
        if (info && [info count]) { break; }
    }
    return info;
}
//打印出來(lái)的結(jié)果:
2016-05-12 15:28:51.674 SimplePing[18883:6790207] WIFI_INFO:{
    BSSID = "a4:2b:8c:c:7f:bd";
    SSID = bdmy06;
    SSIDDATA = ;
}

3.獲取WiFi名稱

有了上一步,獲取WiFi名稱就非常簡(jiǎn)單了。

1
2
3
NSString *WiFiName = info[@"SSID"];
//打印結(jié)果:
2016-05-12 15:35:13.059 SimplePing[18887:6791418] bdmy06

完整的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- (NSString *)fetchWiFiName {
    NSArray *ifs = (__bridge_transfer NSArray *)CNCopySupportedInterfaces();
    if (!ifs) {
        return nil;
    }
    NSString *WiFiName = nil;
    for (NSString *ifnam in ifs) {
        NSDictionary *info = (__bridge_transfer NSDictionary *)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
        if (info && [info count]) {
            // 這里其實(shí)對(duì)應(yīng)的有三個(gè)key:kCNNetworkInfoKeySSID、kCNNetworkInfoKeyBSSID、kCNNetworkInfoKeySSIDData,
            // 不過(guò)它們都是CFStringRef類型的
            WiFiName = [info objectForKey:(__bridge NSString *)kCNNetworkInfoKeySSID];
//            WiFiName = [info objectForKey:@"SSID"];
            break;
        }
    }
    return WiFiName;
}

4.獲取當(dāng)前所連接WiFi的網(wǎng)關(guān)地址

例如自己家的路由器一般默認(rèn)的網(wǎng)關(guān)地址是192.168.1.1,獲取的就是這個(gè)192.168.1.1。

為什么不直接寫(xiě)死呢?

因?yàn)橐恍┥虉?chǎng)或者有多個(gè)路由器的網(wǎng)關(guān)地址是不一樣的,比如之前有個(gè)公司的網(wǎng)關(guān)是192.168.89.1。

這里有篇博客,這是地址

需要導(dǎo)入的庫(kù):

1
#import #import #import

獲取網(wǎng)關(guān)的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
- (NSString *)getGatewayIpForCurrentWiFi {
    NSString *address = @"error";
    struct ifaddrs *interfaces = NULL;
    struct ifaddrs *temp_addr = NULL;
    int success = 0;
    // retrieve the current interfaces - returns 0 on success
    success = getifaddrs(&interfaces);
    if (success == 0) {
        // Loop through linked list of interfaces
        temp_addr = interfaces;
        //*/
        while(temp_addr != NULL) {
        /*/
         int i=255;
         while((i--)>0)
         //*/
            if(temp_addr->ifa_addr->sa_family == AF_INET) {
                // Check if interface is en0 which is the wifi connection on the iPhone
                if([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"])
                {
                    // Get NSString from C String //ifa_addr
                    //ifa->ifa_dstaddr is the broadcast address, which explains the "255's"
                    //                    address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_dstaddr)->sin_addr)];
                    address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
                    //routerIP----192.168.1.255 廣播地址
                    NSLog(@"broadcast address--%@",[NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_dstaddr)->sin_addr)]);
                    //--192.168.1.106 本機(jī)地址
                    NSLog(@"local device ip--%@",[NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)]);
                    //--255.255.255.0 子網(wǎng)掩碼地址
                    NSLog(@"netmask--%@",[NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_netmask)->sin_addr)]);
                    //--en0 端口地址
                    NSLog(@"interface--%@",[NSString stringWithUTF8String:temp_addr->ifa_name]);
                }
            }
            temp_addr = temp_addr->ifa_next;
        }
    }
    // Free memory
    freeifaddrs(interfaces);
    in_addr_t i = inet_addr([address cStringUsingEncoding:NSUTF8StringEncoding]);
    in_addr_t* x = &i;
    unsigned char *s = getdefaultgateway(x);
    NSString *ip=[NSString stringWithFormat:@"%d.%d.%d.%d",s[0],s[1],s[2],s[3]];
    free(s);
    return ip;
}

其中 getdefaultgateway 是一個(gè)C語(yǔ)言文件中的方法,在工程里可以找到。

5.獲取本機(jī)在WiFi環(huán)境下的IP地址

獲取本機(jī)在WiFi環(huán)境下的ip地址,在上一節(jié)中其實(shí)已經(jīng)寫(xiě)過(guò),這里將其提取出來(lái)即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
- (NSString *)getLocalIPAddressForCurrentWiFi
{
    NSString *address = nil;
    struct ifaddrs *interfaces = NULL;
    struct ifaddrs *temp_addr = NULL;
    int success = 0;
    // retrieve the current interfaces - returns 0 on success
    success = getifaddrs(&interfaces);
    if (success == 0) {
        // Loop through linked list of interfaces
        temp_addr = interfaces;
        while(temp_addr != NULL) {
            if(temp_addr->ifa_addr->sa_family == AF_INET) {
                // Check if interface is en0 which is the wifi connection on the iPhone
                if([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) {
                    address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
                    return address;
                }
            }
            temp_addr = temp_addr->ifa_next;
        }
        freeifaddrs(interfaces);
    }
    return nil;
}

同樣的方式也可以獲取廣播地址、子網(wǎng)掩碼、端口等,組裝成一個(gè)字典。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
- (NSMutableDictionary *)getLocalInfoForCurrentWiFi {
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    struct ifaddrs *interfaces = NULL;
    struct ifaddrs *temp_addr = NULL;
    int success = 0;
    // retrieve the current interfaces - returns 0 on success
    success = getifaddrs(&interfaces);
    if (success == 0) {
        // Loop through linked list of interfaces
        temp_addr = interfaces;
        //*/
        while(temp_addr != NULL) {
            if(temp_addr->ifa_addr->sa_family == AF_INET) {
                // Check if interface is en0 which is the wifi connection on the iPhone
                if([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) {
                    //----192.168.1.255 廣播地址
                    NSString *broadcast = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_dstaddr)->sin_addr)];
                    if (broadcast) {
                        [dict setObject:broadcast forKey:@"broadcast"];
                    }
                    NSLog(@"broadcast address--%@",broadcast);
                    //--192.168.1.106 本機(jī)地址
                    NSString *localIp = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
                    if (localIp) {
                        [dict setObject:localIp forKey:@"localIp"];
                    }
                    NSLog(@"local device ip--%@",localIp);
                    //--255.255.255.0 子網(wǎng)掩碼地址
                    NSString *netmask = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_netmask)->sin_addr)];
                    if (netmask) {
                        [dict setObject:netmask forKey:@"netmask"];
                    }
                    NSLog(@"netmask--%@",netmask);
                    //--en0 端口地址
                    NSString *interface = [NSString stringWithUTF8String:temp_addr->ifa_name];
                    if (interface) {
                        [dict setObject:interface forKey:@"interface"];
                    }
                    NSLog(@"interface--%@",interface);
                    return dict;
                }
            }
            temp_addr = temp_addr->ifa_next;
        }
    }
    // Free memory
    freeifaddrs(interfaces);
    return dict;
}

將返回的字典打印出來(lái):

1
2
3
4
5
6
2016-05-12 17:59:09.257 SimplePing[19141:6830567] wifi:{
    broadcast = "192.168.1.255";
    interface = en0;
    localIp = "192.168.1.7";
    netmask = "255.255.255.0";
}

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多