Android NDK层发起HTTP请求的问题及解决

前言

新的一年,大家新年快乐~~鸡年大吉!

本次给大家带来何老师的最新文章~虽然何老师还在过节,但依然放心不下广大开发者,在此佳节还未结束之际,给大家带来最新的技术分享~

事件的起因不说了,总之是需要实现一个 NDK 层的网络请求。为了多端适用,还是选择了 CodeTyphon 作为跨平台方案。关于 CodeTyphon 此处不述,感兴趣的可以直接去其官网查看(传送门:http://www.pilotlogic.com/sitejoom/)。

CodeTyphon 自带的 fcl-web 库可以直接完成对于 HTTP 请求的支持,虽然我很想这么说... 在实际使用中,的确可以通过引入 fcl-web 来完成跨平台的网络请求,然而在 Android 端实际测试时,却发生了奇怪的错误。

比如说请求我自己的服务器 www.rarnu.com,会发生以下错误:

而当我换用 IP 地址来请求时,却是可以成功的。

输入的域名是实际存在的,可以排除掉域名本身的问题。而使用 adb shell 连入设备,并使用 ping 命令访问该域名,也是正常的。

那么问题可能就出在,找不到 nameserver。我们都知道,在 Linux 下,nameserverresolv.conf 决定,这个文件通常保存在 /etc 下。于是看了一下,Android 里并没有这个文件,应该就是这个原因引起的了,因为读不到 resolv.conf 所以才导致了无法解释域名。接下来就是去找 Android 下,原本该是 resolv.conf 的东西保存在哪里。

不卖关子了,其实 Android 很早就把 resolv.conf 的内容改成了 key-value 的形式,采用 SystemProperties 进行存储,而其关键的 key 是 net.dns1net.dns2

尝试使用 adb 连接手机,并对以上两个 key 进行取值:

我的手机上取出来的是 OpenDNS 的值,自己设置过。好了,既然已经知道了 nameserver 的所在,接下去就是修改代码以使程序识别和加载。


在 CodeTyphon 中,有一个基础库文件叫 netdb.pp,其中包含了 resolveName 方法,其具体代码如下:

其实这段代码很明确,关键变量是 DNSServers,打印一下看看是个什么值:

程序执行后打出来 -1,也就是说在 Android 下,由于 DNSServers 变量中没有任何的数据,导致了完全无法解析域名,在其他平台下,在此处打日志均显示 0,表示在这个数组里有一个下标为 0 的数据。

那事情就变得简单了,我们可以直接去找加载了 DNSServers 的地方,很容易的,找到了 InitResolver函数,由于该函数比较长,此处只截取加载 DNSServer 的部分:

没有比这更明确的了,就是去找有没有 /etc/resolv.conf 嘛,找到就加载,没找到那就啥都不做了,而刚才说过了 Android 端并没有这么一个文件,于是直接就导致了 nameserver 缺失,间接引起域名无法解析。

好了,那么简易的解决方案也就有了,只需要重建 GetDNsservers 函数,使其能够适应 Android 端的情况即可。

下面给出代码:

里面还有一个关键代码,是 GetNetDNS,它用于从 Android 内读取 net.dns1 变量:

最后,把上面的 InitResolver 改一下,使其可以正常加载工作于 Android 端的这段代码:

编译运行程序,Error resolving host 的问题即得到了解决。

原文发布于微信公众号 - Android群英传(android_heroes)

原文发表时间:2017-02-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏技术翻译

Kafka和Redis的系统设计

我最近致力于基于Apache Kafka的水平可扩展和高性能数据摄取系统。目标是在文件到达的几分钟内读取,转换,加载,验证,丰富和存储风险源。系统收到银行上游风...

5450
来自专栏三木的博客

Linux基础知识总结

###一:什么是Linux? Linux被称为类Unix操作系统,遵循POSIX标准。Linux与Unix的最大不同在于源代码的开放性和自由性。 Linux的发...

2469
来自专栏数据和云

Linux 内存中的Cache,真的能被回收么?

编辑手记:很多人都认为,Linux中buffers和cached所占用的内存空间是可以在内存压力较大的时候被释放当做空闲空间用的。但真的是这样么?今天我们重新来...

49511
来自专栏FreeBuf

PHP代码审计实战思路浅析

对于面向过程写法的程序来说,最快的审计方法可能时直接丢seay审计系统里,但对于基于mvc模式的程序来说,你直接丢seay审计系统的话,那不是给自己找麻烦吗?

1213
来自专栏unlike

用paxos实现多副本日志系统--multi paxos部分

上篇 basic paxos : https://cloud.tencent.com/developer/article/1147420

3868
来自专栏流柯技术学院

接口测试之webservice

Web service是一个平台独立的,低耦合的,自包含的、基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述、发布、发...

3573
来自专栏蓝天

Unix&Linux下常见的性能分析工具介绍

Vmstat是一个很全面的性能分析工具,可以观察到系统的进程状态、内存使用、虚拟内存使用、磁盘的IO、中断、上下文切换、CPU使用等。系统性能分析工具中,使用...

981
来自专栏北京马哥教育

Python 中的进程、线程、协程、同步、异步、回调

进程和线程究竟是什么东西?传统网络服务模型是如何工作的?协程和线程的关系和区别有哪些?IO过程在什么时间发生? 在刚刚结束的 PyCon2014 上海站,来自七...

4455
来自专栏IT可乐

Linux系列教程(三)——Linux学习技巧

  前面我们讲了Linux系统的详细安装教程,大家跟着教程一步一步的操作,应该能完美的完成安装。那么这篇博客跟大家聊聊如何来学习Linux。 1、工欲善其事必先...

2447
来自专栏linux、Python学习

Linux吃掉了我的内存

在Windows下资源管理器查看内存使用的情况,如果使用率达到80%以上,再运行大程序就能感觉到系统不流畅了,因为在内存紧缺的情况下使用交换分区,频繁地从磁盘上...

1865

扫码关注云+社区

领取腾讯云代金券