什么是IP
IP是Internet Protocol(网际互连协议)的缩写,是TCP/IP体系中的网络层协议。对上可载送传输层各种协议的信息,例如TCP、UDP等;对下可将IP信息包放到链路层,通过以太网、令牌环网络等各种技术来传送
IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。
IP规定网络上所有的设备都必须有一个独一无二的IP地址,就好比是邮件上都必须注明收件人地址。但是一台设备理论上可以有多个IP地址。
IP地址:IP地址是一个32位的二进制数,通常被分割为4个“8位二进制数”(也就是4个字节)。IP地址通常用“点分十进制”表示成(a.b.c.d)的形式,其中,a,b,c,d都是0~255之间的十进制整数。
获取IP的几种方式
一、请求第三方获取
如 http://119.29.29.29/d?dn=www.baidu.com&ttl=1,讲www.baidu.com换成其他域名,即可请求获取到该域名的ip地址。
我们可以看到,百度不只有一个ip,这是CDN的关系(自己下去查)
二、根据私有API获取
(笔者只考虑了iOS11以上的版本)
_timingData私有属性,分别可以从NSURLConnection和NSURLSessionTask对象中获取,(NSURLConnection 需要iOS12的版本支持)
需要注意的是,私有API有被拒审的风险,慎用~要做一些特殊处理,比如通过runtime的方式执行获取,或者对_timingData进行encode处理过机审。
iOS 13以上,NSURLSessionTask可以通过task的代理直接获取,光明正大的拿到ip地址。
NSURLSessionTaskTransactionMetrics.remoteAddress
优势:这种方式有一个极大的好处,就是和本次请求绑定在一次,不需要增加请求的次数,给APP增加流量上的负担。
劣势:如果用户有连接代理,则会拿到代理的ip,这对我们统计来说是没有意义的。
三、ping值获取
(需要一次极小的请求,直接获取到当前请求远端ip,但是可能会有一些偏差,因为ping相当于一次请求,和真实的请求IP可能会存在偏差)
获取时长约为35ms(和网络环境正相关,very bad的网络可能会达到1秒以上)
具体方案参考如下:
https://kangzubin.com/apple-sample-code-simpleping/
https://learnku.com/articles/23788
最终方案:
先判断是否有代理,https://blog.csdn.net/potato512/article/details/88692127
判断是否有代理,第一次约为5ms,之后为0.02ms。切换代理状态时,也会增加时长为毫米级(2ms左右)
如果存在代理,使用ping工具获取;如果不存在,使用私有API
IP存在获取不到的情况,注意判空