有那么一个应用,同样的服务器端,同样的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享受了同等的待遇。
总结:
Android是当前发行量最大的Linux版本。
纠结于“谁比谁强”之类的话题只会耽误事,把结论归结到类似的话题上更是无聊至极。只有用不好,没有不好用!
数据截取之类的所谓黑客技术,有时可以更快的找出问题。
分享到:
相关推荐
Ping 测量发包、丢包、发送时延等数据 Rssi 扫描周边的AP信息,并展示出来 Ftp 实现Ftp客户端的上传和下载,如需使用此功能,需要自己在代码中填写服务器地址、端口号、用户名和密码,否则该功能不可用,现在代码里...
HoloWAN Recorder 是一款可以测量网络的延迟、丢包以及网络抖动的网络环境测量工具。支持 Android、Linux、Windows、Mac。 测量结果可以通过图表展现网络状况。 并且可以录制一段时间内的网络状况,录制结果以txt...
android ping 检查网络 ping网络丢包率 Android中ping检测的使用
Android上可用的用于检查网络的库,该库使用ping或请求url来获取真实的网络状态。 设置 Gradle依赖 在您的模块build.gradle添加以下内容 dependencies { compile 'com.yan.netmanager:netmanager:1.2.0' } 如何...
增加流媒体传输过程中丢包率统计功能并提供查询API接口; Windows平台支持Java语言开发,并提供示例程序源代码; 新增Android 4.1平台支持,并兼容更多Android设备; 修正切换声卡,或是切换音频工作模式时可能...
主要用于网络丢包测试、dns查询、ip计算等等,比较适合没有带电脑小伙伴通过无线网络进行测速
报告结果:iPerf3生成详细的性能报告,包括吞吐量、延迟、丢包率等指标。这些报告可以帮助网络管理员和工程师了解网络连接的质量,并识别任何性能问题。 跨平台支持:iPerf3可在多种操作系统上运行,包括Lin
由于udp丢包比较厉害,因此使用了自定义的内部协议,进行双方的确认。 程序跑起来后,看网络状况,有时候会一卡一卡的。 以下是程序说明: * 本程序集成了数据导出端(服务器端)和数据导入端(客户端),使用UDP...
集成了由云账户提供的红包SDK(https://www.yunzhanghu.com),对于想做红包以及账户管理的开发者,是一种非常值得推荐的解决方案,一是开发者不用头疼于安全问题,以及开发中逻辑不严谨导致的资金转移丢包的问题。
需要的可以下载。在网络上面很难得的!一般里面缺少fastboot.exe!本包中包含
增加流媒体传输过程中丢包率统计功能并提供查询API接口; Windows平台支持Java语言开发,并提供示例程序源代码; 新增Android 4.1平台支持,并兼容更多Android设备; 修正切换声卡,或是切换音频工作模式时可能...
但是,假如ViewPager的每一个Fragment都需要通过网络拉取数据加载,而ViewPager是默认加载前两项的,所以在很容易造成网络丢包或者网络堵塞等问题,所以Fragment使用懒加载是非常有必要的。 举个栗子: 如上图所示...
可以实时显示网速,每秒刷新。由于是监控流量,需要手机产生流量才能计算出网速。 具体用法见demo 可以实时显示网速,每秒刷新。由于是监控流量,需要手机产生流量才能计算出网速。 具体用法见demo
iperf3是基于Client/Server的网络性能测试工具,通常用于测试网络上可达到的最大带宽,它能够测试TCP、UDP及SCTP的带宽质量,可以提供网络吞吐量、网络波动、网络丢包率以及最大传输单元大小等信息,能够帮助我们...
根据HPSocketCS.TcpPackServer server = new HPSocketCS.TcpPackServer();的封包规则进行mina拆包,解决断包,粘包问题。亲测,30ms一次数据,无丢包现象,20MB,300人使用网络,
RK以太网问题汇总以及处理以太网不能使用的办法。资料比较实用
支持音频编解码,对音频数据的压缩率在1~20%之间,且支持动态比特率,从而大幅度降低网络流量,还支持数据包丢失隐藏,当网络丢包率高达30%时,仍然可以进行对讲。 支持视频编解码,支持指定比特率,最低到10KB/s...
手机端通过Ping指令获取指定网络丢包率与延迟率查看网络状态。
自主研发的全面支持高达20%抗丢包、网络自适应的语音编解码,最高到1080P的自主研发高清晰视频话机,甚至在手机/PAD的移动应用上也有移动富媒体能力。视频方面,华为统一通信带来桌面级的高清体验,将视频普及到了...
针对传统车载视频监控系统网络资源利用率...系统实现了P2P和C/S混合网络架构、多线程机制、丢包和包乱序处理,从而提高了实时监控性能。经实验证明,该系统实现了针对车辆的实时高效的监控,利于向智能交通领域中推广。