iOS 开发中难免会遇到很多与网络方面的判断,这里做个汇总,大多可能是与WiFi相关的。

1.Ping域名、Ping某IP

有 时候可能会遇到ping 某个域名或者ip通不通,再做下一步操作。这里的ping与传统的做get或者post请求还是有很大区别的。比如我们连接了某个WiFi,测试ping www.baidu.com,如果能ping 通,基本可以断定可以上网了,但是如果我们做了一个get 请求(url 是www.baidu.com),路由器可能重定向这个WiFi内的某网页了,依然没有错误返回,就会误认为可以正常上网。

这里有关于ping命令的详细解释:百度百科Ping

iOS中想要ping域名或者ip,苹果提供了一个官方例子SimplePing

在例子中,有一个苹果已经封装过的类【SimplePing.h】和【SimplePing.m】

使用起来也相当的简单:

首先创建一个Ping对象:

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

然后在start成功的代理方法中,发送数据报文:

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
 *  start成功,也就是准备工作做完后的回调
 */
- (void)simplePing:(SimplePing *)pinger didStartWithAddress:(NSData *)address
{
    // 发送测试报文数据
    [self.pinger sendPingWithData:nil];
}
- (void)simplePing:(SimplePing *)pinger didFailWithError:(NSError *)error
{
    NSLog(@"didFailWithError");
    [self.pinger stop];
}

其他几个代理方法也非常简单,就简单记录一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 发送测试报文成功的回调方法
- (void)simplePing:(SimplePing *)pinger didSendPacket:(NSData *)packet sequenceNumber:(uint16_t)sequenceNumber
{
    NSLog(@"#%u sent", sequenceNumber);
}
//发送测试报文失败的回调方法
- (void)simplePing:(SimplePing *)pinger didFailToSendPacket:(NSData *)packet sequenceNumber:(uint16_t)sequenceNumber error:(NSError *)error
{
    NSLog(@"#%u send failed: %@", sequenceNumber, error);
}
// 接收到ping的地址所返回的数据报文回调方法
- (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__);
}

注意点:

iOS 中 ping失败后(即发送测试报文成功后,一直没后收到响应的报文),不会有任何回调方法告知我们。而一般ping 一次的结果也不太准确,ping 花费的时间也非常短,所以我们一般会ping多次,发送一次ping 测试报文0.5s后检测一下这一次ping是否已经收到响应。0.5s后检测时,如果已经收到响应,则可以ping 通;如果没有收到响应,则视为超时。

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

这里有一个别人写的工程:https://github.com/lovesunstar/STPingTest

PingTest效果图

终端ping效果图

2.获取WiFi信息

以前物联网刚火的时候,出现过很多一体式无线路由,所以App里难免会遇到要判断当前所连接的WiFi,以及获取WiFi信息的功能。13年的时候查过一些关于WiFi的方法,后面渐渐都忘记了。惭愧!!!

需要添加SystemConfiguration.framework 并在当前类中添加代码#import

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//获取WiFi 信息,返回的字典中包含了WiFi的名称、路由器的Mac地址、还有一个Data(转换成字符串打印出来是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;
}
//打印出来的结果:
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名称就非常简单了。

1
2
3
NSString *WiFiName = info[@"SSID"];
//打印结果:
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]) {
            // 这里其实对应的有三个key:kCNNetworkInfoKeySSID、kCNNetworkInfoKeyBSSID、kCNNetworkInfoKeySSIDData,
            // 不过它们都是CFStringRef类型的
            WiFiName = [info objectForKey:(__bridge NSString *)kCNNetworkInfoKeySSID];
//            WiFiName = [info objectForKey:@"SSID"];
            break;
        }
    }
    return WiFiName;
}

4.获取当前所连接WiFi的网关地址

例如自己家的路由器一般默认的网关地址是192.168.1.1,获取的就是这个192.168.1.1。

为什么不直接写死呢?

因为一些商场或者有多个路由器的网关地址是不一样的,比如之前有个公司的网关是192.168.89.1。

这里有篇博客,这是地址

需要导入的库:

1
#import #import #import

获取网关的方法

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 本机地址
                    NSLog(@"local device ip--%@",[NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)]);
                    //--255.255.255.0 子网掩码地址
                    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 是一个C语言文件中的方法,在工程里可以找到。

5.获取本机在WiFi环境下的IP地址

获取本机在WiFi环境下的ip地址,在上一节中其实已经写过,这里将其提取出来即可:

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;
}

同样的方式也可以获取广播地址、子网掩码、端口等,组装成一个字典。

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 本机地址
                    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 子网掩码地址
                    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;
}

将返回的字典打印出来:

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";
}

iOS开发中获取WiFi相关信息的更多相关文章

  1. iOS开发中获取视图在屏幕上显示的位置

    在iOS开发中,我们会经常遇到一个问题,例如,点击一个按钮,弹出一个遮罩层,上面显示一个弹框,弹框显示的位置在按钮附近.如果这个按钮的位置相对于屏幕边缘的距离是固定的,那就容易了,可以直接写死位置.可 ...

  2. iOS 12中获取WiFi的SSID

    开始搞智能家居,wifi获取不到了?? 小插曲 旧方法失效,19-12-15更新,ios13开始需要请求定位信息 SSID全称Service Set IDentifier, 即Wifi网络的公开名称. ...

  3. iOS开发中虚拟键盘相关的坑

    初学者在学习iOS开发时,遇到在一个textField中输入完内容后却发现虚拟键盘无法隐藏起来而不知所措的情况的人一定不占少数吧.这篇文章就说说我遇到的和虚拟键盘有关的三个问题及解决对策. 在模拟器测 ...

  4. NX二次开发-UFUN获取系统相关信息UF_ask_system_info

    NX9+VS2012 #include <uf.h> UF_initialize(); UF_system_info_t Info; UF_ask_system_info(&Inf ...

  5. IOS开发中获取当前WIFI的名字

            ifs = [self fetchSSIDInfo]; ssid = [ifs objectForKey:@"SSID"]; self.sSIDTxt.textFi ...

  6. iOS开发中与库相关的术语

    动态库 VS 静态库 Static frameworks are linked at compile time. Dynamic frameworks are linked at runtime

  7. iOS开发之获取WIFI信号强度

    虽然各种直接获取信号强度的api都被封杀了.但是还有一个另类的黑魔法可以获取到.那就是遍历UIStatusBar了 - (void)getSignalStrength{ UIApplication * ...

  8. iOS开发中获取文本的宽高的方式

    /** 计算单行文字的size @parms  文本 @parms  字体 @return  字体的CGSize */ + (CGSize)sizeWithText:(NSString *)text ...

  9. 【iOS开发】获取wifi的SSID

    #import <SystemConfiguration/CaptiveNetwork.h> NSArray *ifs = (__bridge_transfer id)CNCopySupp ...

随机推荐

  1. 图片切换小demo

    <body> <div class="body"><img src="bopin/images/bigImg1.jpg" widt ...

  2. js 中 substring() 和 substr() 提取字符

    提取字符串substring() substring() 方法用于提取字符串中介于两个指定下标之间的字符. 语法: stringObject.substring(startPos,stopPos)  ...

  3. yii2.0 框架邮件的发送

    第一步: 在main-local.php中的components中配置mailer: $config = [ 'components' => [ 'mailer' => [ 'class' ...

  4. struts2+jsp+hiberbate 双重遍历

    今天弄了个双重遍历,由于自己水平有限,做了好久才搞定. 例子如下:也不算是例子,简要代码吧 action中有属性: private List<Contents> content; 其中co ...

  5. ssh 不能连上服务器 hosts.deny没有没限制ip 找不到什么原因

    [root@NB Downloads]# ssh -p22022 -vv .5x.xx.xxx OpenSSH_5.3p1, OpenSSL Feb debug1: Reading configura ...

  6. 几年前做家教写的C教程(之四专讲了指针与汉诺塔问题)

    C语言学习宝典(4) 指针:可以有效的表示复杂的数据结构,能动态的分配动态空间,方便的使用字符串,有效的使用数组,能直接处理内存单元 不掌握指针就没有掌握C语言的精华 地址:系统为每一个变量分配一个内 ...

  7. mac 下 用 glfw3 搭建opengl开发环境

    mac 下 用 glfw3 搭建opengl开发环境 下载编译 glfw3 Build Setting 里面, Library Search Paths -> 设置好编译 glfw 库的路径 H ...

  8. ajax 传递JSON对象参数

    https://msdn.microsoft.com/zh-cn/library/cc836466(v=vs.94).aspx https://msdn.microsoft.com/zh-cn/lib ...

  9. js的回调函数 一些例子

    这边用bootstrap 3.0的  上传控件做例子 下面是上传控件的一段完整的 js 操作 代码. <!-- 上传缩略图控件配置 --><script> // 定义这四个全局 ...

  10. php 冒泡 快速 选择 插入算法 四种基本算法

    php四种基础算法:冒泡,选择,插入和快速排序法 来源:PHP100中文网 | 时间:2013-10-29 15:24:57 | 阅读数:120854 [导读] 许多人都说 算法是程序的核心,一个程序 ...