当前位置:C++技术网 > 精选软件 > 计时器的使用经验总结:2 超时检测和超时处理

计时器的使用经验总结:2 超时检测和超时处理

更新时间:2016-06-03 22:21:39浏览次数:1+次

    在文章《计时器的使用经验总结1:时间显示和计时(正向计时和倒计时)以及周期触发》中,我们详细的探讨了计时器在计时和时间显示以及周期性方面的应用。本文再对计时器在超时检测和超时处理方面的使用进行探讨。
    超时检测是网络协议中最基本的特性。当然,不仅仅是网络,生活中各种超时检测和超时处理。比如过期作废,合同超期赔款等等。超时检测的超时,似乎是等待一个时间,然后触发一个事件,然后处理事件。这么一说,其实和计时如出一辙。但是,并没有那么直观。一说到超时,其实很多人大脑里没有形成计时器应用方案。
    我在做网络连接状态检测的时候,应用到了超时检测,所以也就在此讨论一番。我们一般应用计时器都是定期去触发一件事情,而超时则是定期去检查一个状态。两者稍微有一点点区别。我来仔细分析一下超时检测问题。
    超时检测处理相对于计时应用要复杂一点。因为计时的话,到了时间执行一个动作就好了。逻辑上简单明了。而超时检测,则要处理状态变化的逻辑。当设定一个超时时间后,实际上,也就是设置了计时器触发的间隔时间。这个和计时应用一样。但是,超时时间和计时器间隔的对应,有些人经验不多的,还真的一下子反应不过来。
    因为根据我们的生活逻辑,超时就是一段时间达到了,然后做一件事情。然后就完了。生活的逻辑让我们没有往后面想更多,当然生活经验丰富的,也是有点感觉的。比如借图书,超期一个月,扣多少钱,超期两个月扣多少钱,超期三个月注销用户加罚款。在生活中,我们都是尽可能的避免超期,因为代价一般都比较高。所以在简单的听说超时时,没有发现超时应用里隐藏着周期性的特点,所以一下子联想不到计时器。这个很正常,当你开发经验丰富后,也就很快想得到。
    如果只是一次超时,然后激发事情,那和计时应用没有什么两样。超时检测和超时处理,和简单的计时处理方式不一样,也就是事件触发时要做的事情逻辑上有些不一样。
    在联网应用里,我们经常要检测联网状态。如果网络断开,则无法进行网络通信了。我们需要时刻知道网络的状态,才好做接下来的工作。
    我们如何判断网络状态呢?实际上,超时检测和超时处理就是对状态的检测和处理。而超时检测必然是定期的检测,这也就让计时器发挥了作用。
    那么什么样的状态叫做联网在线状态呢?什么样的状态又叫做断网状态呢?我们如何检测状态,依据是什么呢?
    我们所知道的联网状态,在逻辑上是持续不断的,实际上,并不是这样的。有时候我们在软件界面上看到的联网在线状态,实际上已经处于断网状态了。所以看似连着网,实际上你消息却怎么也发不出去。为什么会这样呢?
    软件界面上呈现的网络状态,只是软件的一个逻辑的处理。而实际上,可能已经断网无法通信。
    我们通常的思维就是,计算机会自己检测是否联网,然而我们在编程的时候,所有这一切都是由程序员来实现的,我们不能依赖系统的检测,而是要用自己的一套逻辑来实现。这一点可能难倒了一些人。难点就在于思维逻辑,如果总是陷在系统的联网状态逻辑中,那么你很可能总是找不到检测连接方法。
    实际上,连接并不需要每时每刻都保持交流,联网状态的检测,我们只关心你死了没有! 那么你只要在合适的时间内,跟我说一句你还活着,我就知道你还没有死,这样我就觉得我们还彼此依靠着。那么这个合适的时间,我们将它术语化,就叫做超时时间。如果在这个规定的时间内,你没有给我说话,我觉得你就死掉了。因为这个合适的时间内,正常的情况,是不可能不说话的。所以这也是超时时间判断连接是否持续的依据。
    我们说了一次话,我们知道我们此时彼此都还活着,但是我们得一直持续监测,一直确定相互还可以依靠。所以,超时检测并不只是一段时间的事情,而是一直维持的。说不定,刚说完话,下一秒就被死神剥夺了生命。世界太不确定了。
    所以,联网和断网状态显示,和超时时间有关系。我们假设在超时时刻到来之前的一段时间内,网络是联通的,那么超时时刻到来时,我们就认为此时还没有得到对方的消息,就表明已经断开网络。我暂且将这个检测方法叫做求死检测。在求死检测中,超时时刻到来之前,也就是计时器累计时间还未到达超时时间长度时,任何一个通信都会让计时器重置,也就让计时器重新计时,所以持续的通信,可以让计时器不断的重置,也就无法累计到超时时间长度。万一网络真的断了,在超时时间累计到达之前,是无法收到消息的,这样计时器就不断的累计计数,然后就到达了超时时间,这样就检测到了断网状态了。
    那么你可以看到,在你检测到断网状态时,网络可能早就断开了。所以,你看到的联网状态实际上只是一个假象。超时时间越短,检测也就越灵敏。这样网络的状态变化很快就被检测到了。但是对于通信不是很频繁的情况,我们不能将超时时间设置的太短了,否则就出现大量的断网状态的显示。而实际上在双方是可以通信的。这叫做说话虽少但不能当他死了。
    而超时检测可以用在各种场景,我们可以用来检测联网状态是否断网,也可以用来检测是否上线等等。实际上,超时就是在指定的时间内,如果到了超时时间,就要判定一种状态,而这个状态和超时时间内的状态一定要是相反的。前面说了求死检测,那么相反来看的话,就是求生检测。超时时刻到来前都是死的状态,超时时候检测则可能得到生的状态。
    在编程中,超时检测并不是对变量做累加,而是状态的反转。如果要检测是否断网,那么表示,开始的时候一直维持的是联网状态。我们的计时器设置一个间隔时间,当间隔时间到来的时候,就表示断网了。这样设计的原理在于,联网的时候,对方可以在计时器触发前发来消息,这样我们就可以重置计时器,让计时器重新累计时间。重置计时器后,相当于对记录网络状态为联网的变量进行了保护,只要计时器没有触发,没有将这个变量设置为断网状态,那么我们看到的都是联网状态。所以程序上实现还是很简单的。
    平时的通信则具有随机性,不能安全确保网络的连接。万一什么时候没有通信,服务器认为断网了,然后断开了连接,那就真的断网了。所以一般有一个叫做心跳包的机制。客户端定期发送一个心跳包的消息给服务器,只要服务器收到心跳包,就会重置断网检测计时器,这样也就维持了网络的连接状态,服务器就不会断开连接。心跳包就是一个很小的数据包,就是用来告知服务器,你收到了客户端的消息,你也就知道了客户端还存活着,不能断开网络连接。当然,其他的非心跳包的正常数据包,自然也可以使计时器重置,因为他们也可以表示客户端存活着。所以,不断的通信也就不断的重置计时器,才让我们感觉网络一直连接着。
    超时检测,只是对状态的一种逻辑上的检测,并不是物理上的网络检测。所以,很多时候软件上看到的网络状态并不能真实反映物理的网络状态。
    实际上,超时检测和超时处理在很多地方都有应用,这里就只是拿网络联网状态检测做一个例子,希望已经将计时器在超时检测方面的应用说明白了。如果哪里还没有表述清楚,请指正。如果有疑问,请留言。