Android端TCP长连接的性能优化教程分享

 更新时间:2018年03月11日 08:59:03   作者:冰冰  
在开发过程中,我们经常会用到TCP/IP连接实现即时数据传输,下面这篇文章主要给大家介绍了关于Android端TCP长连接的性能优化的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧。

前言

大家应该都知道,在Android端实现TCP长连接场景其实不多,我们最熟悉的不过推送和HTTP协议的实现(OkHttp),本文讨论的是在实现推送长连接的情况下怎么来做性能优化,下文只是我的一点拙见,有不妥之处还望指出,下面话不多说了,来一起看看详细的介绍吧。

推送长连接

可以说大部分APP是离不开推送(push)这个功能的,不过平常我们都是接入第三方SDK(极光、个推等)居多,因为要做一个推送服务,不光客户端要编写相应的Socket通信代码,服务器端更是麻烦,要处理大规模的长连接服务,消息还得及时送达,一两台服务器可是吃不消。相对来说客户端编写Socket通信的代码会简单一些,但是也是要处理一些平台相关的问题,比如推送服务进程如何保活,APP进程如何跟推送服务进程通信,如何节省手机电量和手机弱网情况下如何提升通信质量等一系列的问题。这些问题以后有时间分析,下面来看看TCP长连接性能如何来优化

影响TCP性能的点

TCP/IP体系太复杂了,想完全掌握确实很困难,我们只分析影响TCP性能的几个因素,看看在Android客户端可不可以进行优化

TCP连接的三次握手时延

我们知道要建立TCP连接,需要经过三次握手,三次握手成功后连接建立成功

  • 客户端请求新的连接,需要发送一个设置了SYN标记的分组,向服务器说明这三个连接请求
  • 如何服务器接受了这个连接请求,会向客户端回送一个设置了SYN和ACK的分组,向客户端说明连接请求已经被接受了
  • 客户端收到这个表明连接请求被接受的分组后,要发送一条携带ACK标记的确认消息(可能会在这个消息中携带业务数据)表明连接已经建立成功了,可以开始发送数据了

那建立TCP连接的三次握手而产生的时延对我们会有影响吗,大部分情况下是没有的,只有当HTTP请求传输的数据量比较小,然后呢这样的HTTP请求又非常频繁,这样算下来,握手产生的时延占比就很高了,这种情况下就要通过重用已有的连接来减少连接的次数。而推送长连接本身就是在保持连接的稳定性,无需在这点上进行优化

延迟确认

由于因特网本身无法保证可靠的分组传输,TCP就自己实现确认机制来确保数据的可靠传输,成功接收TCP分组数据的接收者都需要向发送者回送一个小的确认分组,发送者在一定的时间内没有收到这个确认分组,就认为之前发送的数据没有成功,然后会重发数据

但是由于确认分组非常的小,TCP为了有效的利用网络,会把确认分组塞到同向传输数据中去,组合在一起发送传输,如果在一定的时间内没有同向传输数据咋办,岂不是一直会重发?TCP肯定不会允许这种情况发送的,TCP针对这种情况实现了一种延迟确认算法,在一定的窗口时间(一般是100~200毫秒),确认分组还没有被捎带的话,那么确认分组就会单独发送

根据自己之前编写TCP长连接的经验,一般会在应用层设计一个业务ACK包机制,当收到一个业务数据时,马上会回送一个业务层的ACK包,这个业务层的ACK包就是同向传输数据,确认分组马上会被捎带,不会触发延迟确认算法,但是如果我们收到的消息频率很高,那产生的ACK包就会非常的多,再假设业务层的ACK包并不需要那么的及时,我们是否可以组合业务层ACK包再发送呢?

TCP慢启动

TCP连接的性能还受到拥塞控制机制的影响,当TCP连接刚开始连接上时,并不能一下子就发送很多的分组,可能是一开始只能发送一个分组,然后收到确认分组后,就可以发送两个分组,然后就是四个分组,以此类推。这个就是TCP慢启动,发送数据的能力是慢慢提升的

由于我们编写的是长连接,这种机制对我们的影响并不大

Nagle算法

由于TCP并没有规定每个分组最小值,所以我们可以每次都传输一个字节的数据,但是TCP有固定的标记和首部(至少40个字节),如果TCP发送大量的包含少量数据的分组时,网络的真实利用率就很低,网络整体性能会严重的下降。

所以呢TCP利用了Nagle算法,在发送了一个分组前,将大量TCP数据绑定在一起,提高网络的效率。Nagle算法鼓励发送全尺寸的分组,而且只有当所有的分组都被确认后,才能发送非全尺寸的分组,不然的话就缓存起来,直到积累足够发送一个全尺寸分组数据时才会将缓存的数据发送出去

那这个对我们编写TCP长连接时有什么影响呢,由于我们的心跳包和ACK包一般都很小,那么服务端就不能及时收到我们的心跳包和ACK包,会产生时延,可以通过下面的代码来禁用Nagle算法

Socket.setTcpNoDelay(true);

TIME_WAIT累积与端口耗尽

这个跟服务端相关,一般与客户端没什么关系,这里就不说了

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

相关文章

  • ViewPager+RadioGroup仿微信主界面

    ViewPager+RadioGroup仿微信主界面

    这篇文章主要为大家详细介绍了ViewPager+RadioGroup仿微信主界面,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12
  • Android蓝牙的开启和搜索设备功能开发实例

    Android蓝牙的开启和搜索设备功能开发实例

    这篇文章主要介绍了Android蓝牙服务启动搜索流程,了解内部原理是为了帮助我们做扩展,同时也是验证了一个人的学习能力,如果你想让自己的职业道路更上一层楼,这些底层的东西你是必须要会的
    2023-04-04
  • Android中FTP上传、下载的功能实现(含进度)

    Android中FTP上传、下载的功能实现(含进度)

    本篇文章主要介绍了Android中FTP上传、下载(含进度),具有一定的参考价值,有需要的可以了解一下。
    2016-11-11
  • Anroid四大组件service之本地服务的示例代码

    Anroid四大组件service之本地服务的示例代码

    本篇文章主要介绍了Anroid四大组件service之本地服务的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • AndroidStudio项目打包成jar的简单方法

    AndroidStudio项目打包成jar的简单方法

    JAR(Java Archive,Java 归档文件)是与平台无关的文件格式,它允许将许多文件组合成一个压缩文件,在eclipse中我们知道如何将一个项目导出为jar包,供其它项目使用呢?下面通过本文给大家介绍ndroidStudio项目打包成jar的简单方法,需要的朋友参考下吧
    2017-11-11
  • 详解Android项目多服务端接口适配(超简单)

    详解Android项目多服务端接口适配(超简单)

    这篇文章主要介绍了Android项目多服务端接口适配(超简单),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • Android开发双向滑动选择器范围SeekBar实现

    Android开发双向滑动选择器范围SeekBar实现

    这篇文章主要为大家介绍了Android开发双向滑动范围选择器SeekBar实现,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • Android悬浮窗的实现步骤

    Android悬浮窗的实现步骤

    最近想做一个悬浮窗秒表的功能,所以看下悬浮窗具体的实现步骤,接下来通过本文给大家介绍Android悬浮窗的实现,需要的朋友可以参考下
    2024-01-01
  • Android自定义实现开关按钮代码

    Android自定义实现开关按钮代码

    经常可以看到一些选择开个状态的配置文件,但是外观都不多好看。我感觉还是自定义的比较好,下面小编给大家介绍通过Android自定义实现开关按钮代码,感兴趣的童鞋一起学习吧
    2016-05-05
  • Android 屏蔽和捕获Home键的示例代码

    Android 屏蔽和捕获Home键的示例代码

    本文主要介绍 Android 屏蔽和捕获Home 键的方法,并附有代码实例参考,在开发过程中可能会遇到这样的功能,有需要的同学可以参考下
    2016-07-07

最新评论