有那么一个应用,同样的服务器端,同样的Wi-Fi网络下,Android连接速度总是慢过iphone一个数量级。起先怀疑跟Android的硬件有关,无奈的是通过3G甚至于2G EDGE无线连接,速度均超过Wi-Fi。然后这个责任就一把归结到了“Android不如iPhone”,“Android七拼八凑”之类无休止的平台沙文主义之上了。

接手这个问题之后,起先也是渺无头绪。先从服务器端的结构说起吧。

服务器端,很具有中国特色的电信、联通、移动3入口结构,分别通过DNSpod指定到了3台Haproxy前端,通过这3台Haproxy主机发送请求到3台Server,理所当然的3台Server公用一套数据层。通讯协议并非通用协议,为自身设计的一套基于XML的数据通讯协议,所有的通讯都是TCP的持久连接。服务器端结构

起初的弯路也是被平台沙文主义带到了一个误区,我总是觉得Android手机的问题很可能是硬件驱动对于wi-Fi的支持不好。于是找来了一部手机,几乎刷遍了所有能支持的通用Rom,无奈没有任何起色。(话说Android刷机真的会上瘾:mrgreen: )

然后就是怀疑Android的DNS跟iPhone的不同,无奈两部手机的DNS均是统一DHCP获得的。

回到网络层上来,通过在路由器上监控Android的连接,终于发现Android会有经常性的连接丢包,发起连接很容易失败。单由于是长连接的关系,一旦连接建立成功之后,后续的通许就会很畅通。

说实话,那个时候还是有偏见,认为可能是手机跟路由器的兼容有问题,于是更换了数个路由器,从802.11a一直测到802.11an!不加密的,WEP的,PSK的等等试了个遍,依旧没有进展。忽然发觉这种尝试很可笑,于是自己在内网中写了一个服务端模拟器,发觉没有出现丢包,连接通畅。于是在外网中试环境中,去掉了haproxy层,直连服务器,连接畅通!

问题已经大致上定位了,就是在Haproxy上!!难题才刚刚开始……

更换了多个版本的Haproxy,无效!

怀疑是Android的内核TCP设置有问题(比如滑动窗口,缓存之类的),由于Android本身就是一个Linux,直接Root之后(刷机积攒的经验啊!)把/proc/sys/net路径拷贝下来,一个个文件的对照,一个个配置的试了一天(触摸屏打字很痛苦啊),几乎已经按照服务器的要求配置了一台手机,毫无进展。

好吧,逼我动用终极手段了!数据截取!

刷回原版Rom,连接内网服务器模拟器,通过sniff对所有的通讯数据截包,区分iPhone和Android信包的不同。多次试验之后,发现iPhone和Android每次的信包大小均不一致。Android信包总是大个12字节,终于找到问题了!

net.ipv4.tcp_timestamps

这个内核开关的含义是会在每个信包前增加一个符合RFC 1323标准的时间戳,正好12位。这个配置中,基于Linux内核的操作系统包括Android是默认开启的,但BSD系统,包括iOS中类似的设置是关闭的。

把Rom刷回可root,直接修改内核这个配置,效果立竿见影!应该是解决问题了,但总不能告诉用户“如果你们用Wi-Fi连接不了主机就直接去修改内核配置!”。

分析下来整个问题应该如此:

Haproxy可能存在 bug,或者我们配置有误。Haproxy在转发时可能会出现畸变的数据包,导致数据无法被送达到服务层。但这种状况并不是每次都能被激发(我偏向解释为这是Haproxy的bug)。看了下Haproxy的文档,他们只能解包Http,对于非Http的tcp协议,更多的只是转发数据包而已。对于说为什么手机网络不会受这个影响,个人觉得Android并不是单纯的一个给手机准备的操作系统,移动网络配置并不是存在于内核之中的,电话也好,移动网络也好,是通过应用程序层实现的功能。

畸变的数据包

好吧,把Haproxy的主机全部设置为net.ipv4.tcp_timestamps=0,Android马上跟iPhone享受了同等的待遇。

总结:

  1. Android是当前发行量最大的Linux版本。

  2. 纠结于“谁比谁强”之类的话题只会耽误事,把结论归结到类似的话题上更是无聊至极。只有用不好,没有不好用!

  3. 数据截取之类的所谓黑客技术,有时可以更快的找出问题。


更多相关文章

  1. 用fastboot大刷Android ~换个方法刷android手机
  2. android与linux内核对比--《Android系统源代码情景分析》试读
  3. Android内核开发:源码的版本与分支详解
  4. pandaboard ES学习之旅——5 Android Linux内核源代码下载与编译
  5. 禁止手机横竖屏
  6. 基于Socket的Android手机视频实时传输
  7. Android手机震动抖动效果的实现
  8. Android VNC Server on G1 (PC 远程控制 Android 手机)

随机推荐

  1. scrollTo 以及 scrollBy方法使用说明
  2. Android——XML解析
  3. Android启动模式总结
  4. android 设置静态wifi地址
  5. Android消息机制 Handler
  6. Java如何操作Android的adb shell 之 我自
  7. Android GPS状态改变与监听
  8. Android(安卓)中 Retrofit 结合 RxJava使
  9. Android 软键盘小知识点
  10. (4.2.9)【android开源工具】Android(安卓)O