WIFI相關(guān)功能總結(jié)

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,蘋果提供了一個(gè)官方例子SimplePing
在例子中甥郑,有一個(gè)蘋果已經(jīng)封裝過(guò)的類【SimplePing.h】和【SimplePing.m】
使用起來(lái)也相當(dāng)?shù)暮?jiǎn)單:
首先創(chuàng)建一個(gè)Ping對(duì)象:

SimplePing *pinger = [[SimplePing alloc] initWithHostName:self.hostName];
 self.pinger = pinger;
 pinger.delegate = self;
 pinger.addressStyle = SimplePingAddressStyleICMPv4;
 [pinger start];

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

/**
 *  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)單記錄一下:

// 發(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è)別人寫的工程:https://github.com/lovesunstar/STPingTest

2.獲取WiFi信息
以前物聯(lián)網(wǎng)剛火的時(shí)候萍丐,出現(xiàn)過(guò)很多一體式無(wú)線路由,所以App里難免會(huì)遇到要判斷當(dāng)前所連接的WiFi放典,以及獲取WiFi信息的功能逝变。
需要添加SystemConfiguration.framework 并在當(dāng)前類中添加代碼#import

//獲取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)單了弥臼。

NSString *WiFiName = info[@"SSID"];

完整的:

- (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烙肺。
因?yàn)橐恍┥虉?chǎng)或者有多個(gè)路由器的網(wǎng)關(guān)地址是不一樣的,比如之前有個(gè)公司的網(wǎng)關(guān)是192.168.89.1氧卧。
需要導(dǎo)入的庫(kù):

#import #import #import    //此處由于時(shí)間原因有所遺忘桃笙,后期會(huì)給予更改

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

- (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)寫過(guò),這里將其提取出來(lái)即可:

- (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è)字典粗悯。

- (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;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末虚循,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子为黎,更是在濱河造成了極大的恐慌邮丰,老刑警劉巖行您,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件铭乾,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡娃循,警方通過(guò)查閱死者的電腦和手機(jī)炕檩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)捌斧,“玉大人笛质,你說(shuō)我怎么就攤上這事±搪欤” “怎么了妇押?”我有些...
    開封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)姓迅。 經(jīng)常有香客問(wèn)我敲霍,道長(zhǎng),這世上最難降的妖魔是什么丁存? 我笑而不...
    開封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任肩杈,我火速辦了婚禮,結(jié)果婚禮上解寝,老公的妹妹穿的比我還像新娘扩然。我一直安慰自己,他們只是感情好聋伦,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開白布夫偶。 她就那樣靜靜地躺著界睁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪兵拢。 梳的紋絲不亂的頭發(fā)上晕窑,一...
    開封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音卵佛,去河邊找鬼杨赤。 笑死,一個(gè)胖子當(dāng)著我的面吹牛截汪,可吹牛的內(nèi)容都是我干的疾牲。 我是一名探鬼主播,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼衙解,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼阳柔!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起蚓峦,我...
    開封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤舌剂,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后暑椰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體霍转,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年一汽,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了避消。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡召夹,死狀恐怖岩喷,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情监憎,我是刑警寧澤纱意,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站鲸阔,受9級(jí)特大地震影響偷霉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜隶债,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一腾它、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧死讹,春花似錦瞒滴、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)虏两。三九已至,卻和暖如春世剖,著一層夾襖步出監(jiān)牢的瞬間定罢,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工旁瘫, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留祖凫,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓酬凳,卻偏偏與公主長(zhǎng)得像惠况,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子宁仔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容