套接字连接和轮询,哪种在电池寿命方面更好?

42

所以...我正在为Android制作一个应用程序,该应用程序需要发送和接收实时聊天数据(需要套接字),但它还需要发送命令(当客户端发送某些内容时不需要)。

我需要知道在节省用户电池方面哪种解决方案更好。

a)每次发送命令时打开和关闭连接,如果聊天选项卡已打开,则保持连接恒定。

b)始终保持连接恒定。

我在互联网上看了一下,得到了各种各样的答案,有些人说保持持久连接对电池寿命不利,而有些人则说不会(例如:“您是否在问保持TCP连接是否会耗尽电池寿命?也许我非常偏离主题,但保持连接不应浪费电池寿命…如果您认为这将是我很想知道您从哪里得到了这些信息。这对我来说听起来很奇怪。”

或者如果有其他更好的解决方案。 我认为Google的C2DM在这种情况下也不是很有用。

基本上,什么会更耗电:保持持久连接还是除非聊天选项卡打开否则打开和关闭连接?

谢谢!


1
似乎很合理地假设轮询会消耗更多的电力,因为每次进行轮询时都要打开和关闭连接(除了来回发送数据)。我想如果已经有人对此进行了基准测试,那我倒是会感到惊讶,所以也许你需要成为第一个来得到具体的答案。 :) - Josh1billion
3个回答

67
保持TCP连接处于空闲状态(即没有数据发送或接收)不会比关闭连接消耗更多的电池电量,或者至少不应该会。这是因为空闲的TCP连接不使用带宽或CPU周期(*).
尽管如此,长时间保持TCP连接打开可能对移动设备来说并不是一个好选择,因为TCP连接与进入睡眠状态的计算机不兼容。问题场景如下:当您的Android用户将其Android设备置于睡眠状态而您的应用程序正在运行时,远程用户的程序(或TCP连接另一端的任何内容)通过TCP流发送一些数据。由于Android设备自然处于睡眠状态,因此远程用户的程序从未收到Android设备发回的任何ACK信息,因此远程设备的TCP堆栈认为其发送的TCP数据包必须已经丢失,并通过增加其超时期限、减小其TCP窗口大小(也称“一次允许在飞行中发送的TCP数据包数”)和重新发送TCP数据包来响应。但是Android设备仍处于睡眠状态,因此同样的情况会再次发生。结果是,几分钟后,TCP连接的远程端已经减速到即使Android设备醒来,TCP连接也很可能过慢以至于无法使用 - 在这种情况下,您的程序将需要关闭停顿的TCP连接并重新启动一个新的,这样为什么要费力地尝试保持它打开呢?
因此,我的建议是选择选项(a),并将关闭TCP连接作为Android设备进入睡眠状态时的一部分。
可能有一个例外情况是,如果Android有一个功能,在某些情况下保持TCP连接打开会导致WiFi或蜂窝网络硬件保持通电状态 - 如果是这种情况,那么Android设备将支付电池电量来供电天线,本来不需要支付的。我不知道是否有类似于Android的逻辑,但我只使用过Android一点,所以这可能只是我的无知。至少值得测试一下。

(*) 技术上说,TCP 在连接保持打开状态时会定期发送一个“保活”数据包,这确实会使用一些 CPU 循环和天线功率……但在 Android 上发送保活数据包的默认间隔是两个小时,因此我不认为由此使用的电量会引起注意。


3
TCP默认不发送保持活动数据包。只有在套接字上启用了该选项时,TCP才会发送保持活动数据包。您必须启用它。我建议将其禁用并自行执行心跳检测。根据我的经验,管理自己的心跳检测更好,因为它可以让您知道连接的客户端是否出现故障,而自动的TCP keepalive可能无法告知此情况。 - William Morrison
@WilliamMorrison “管理自己的心跳!!” 这里意味着什么? - Rahul Rastogi
1
这意味着发送自己的心跳数据包。心跳周期性地发生。这是必要的,因为如果您有2个连接的TCP套接字,并且两者都没有发送数据,则它们可能已连接或未连接。您需要尝试传输数据以确认套接字仍然连接着。 - William Morrison
感谢您的深入回答。请问您能否提供任何相关参考资料,证明空闲的TCP套接字连接在不到2小时的情况下不会消耗任何CPU周期吗? - BajajG
只需让您的应用程序在睡眠模式下保持唤醒状态。 - Magmatic
显示剩余4条评论

1
电池寿命与3G网络的DCH/FACH/IDLE状态转换密切相关。如果想要一个节能的应用程序,应该在有限的时间间隔内尽可能发送尽可能多的数据,无论是否存在持久连接...

1

为了实际保持连接,你可能需要来回发送心跳信号,因为在安卓设备和你的服务器之间有任何有状态路由器会在相对短的时间内超时后忘记该连接。

哪个更好取决于你认为需要多长时间才能不需要连接到服务器。如果你大部分时间都是每30秒左右连接一次,那么绝对要保持连接,但如果不是,关闭它可能会更好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接