A. iOS 即時通訊(二):心跳保活
很多人認為,TCP協議有KeepAlive機制,為何基於它的通訊鏈接仍然需要在應用層實現額外的心跳保活呢?本文將從移動端IM的角度告訴你,即使使用的是TCP協議,應用層的心跳保活仍舊必不可少。
在使用TCP長連接的IM服務設計中,往往都會涉及到心跳。心跳一般是指客戶端每隔一定時間向服務端發送自定義指令,以判斷雙方是否存活,改喊因其按照一定間隔發送,類似於心跳,故稱為心跳指令。
TCP是一個基於連接的協議,其連接狀態是由一個狀態機進行維護,連接完畢(三次握手)後,雙方都會處於established狀態,這之後的狀態並不會主動進行變化。也就是說,即使上層不進行任何調用,一直使TCP連接空閑,那麼它仍然是保持連接的狀態。這個時候就需要一種機制來檢測TCP連接的狀態,KeepAlive就是背負這個使命出現的。
那麼問題來了,KeepAlive是用來檢測TCP連接狀態的,那為什麼還需要心跳呢?這里就需要考慮一種情況了,假如某台伺服器因為某些原因導致負載超高,CPU100%,無法響應任何業務需求,但是使用TCP探針仍舊能夠確定連接狀態,這就是典型的連接活著但業務提供方已死的狀態塌廳,對客戶端而言,這時最好的選擇就是斷線後重新連接其他伺服器,而不是一直認為當前伺服器是可用狀態,一直向當前伺服器發送些必然後失敗的請求。
從上面我們可以知道,KeepAlive並不適合檢測雙方存活的場景,這種場景還得依賴於應用層的心跳。應用層的心跳有著更大的靈活性,可以控制檢測時機、間隔和處理流程,甚至可以在心跳包上附帶額外信息。從這個角度而言,應用層的心跳的確是最佳實踐。
TCP KeepAlive用於檢測連接的死活,而心跳機制則附帶一個額外團殲隱的功能:檢測通訊雙方的存活狀態。
從上面我們可以得出結論,目前而言,應用層心跳的確是檢測連接有效性,雙方是否存活的最佳實踐,那麼剩下的問題就是怎麼實現。
最簡單粗暴的方法是定時心跳,如每隔30秒心跳一次,15秒內沒有收到心跳包則認為當前連接已失效,斷開連接並進行重連。這種做法最直接,實現也簡單。唯一的問題就是耗電和耗流量。以一個協議包 5 個位元組計算,一天收發 2880 個心跳包,一個月就是 5 x 2 x 2880 x 30 = 0.8 M 的流量,如果手機上多裝幾個 IM 軟體,每個月光心跳就好幾兆流量沒了,更不用說頻繁的心跳帶來的電量損耗。
既然頻繁心跳會帶來耗電和耗流量的弊端,改進的方向自然就是減少心跳頻率,但也不能過於影響連接檢測的實時性。基於這個需求,一般可以將心跳間隔根據程序狀態進行調整,當程序在後台時(這里主要指安卓),盡量拉長心跳間隔,5分鍾、甚至10分鍾都可以。
而當App在前台時則按照原來規則操作。連接可靠性的判斷也可以放寬,避免一次心跳超時就認為連接無效的情況,使用錯誤積累,只在心跳超時n次後才判定當前連接不可用。
B. java程序裡面心跳響應是什麼意思
就是客戶端與伺服器端連接斷開與否的檢測,一般用於檢測連接是否超時
C. 求linux c語言的心跳包程序
首先,心跳包一般是純稿胡30秒或者1分鍾一次才正常,3秒一次太頻繁,耗損資源,降低效率,心跳包其實就是你自己定義敬世一條數據send給伺服器,伺服器recv到這條數據做下判斷就行了,如果1分鍾沒做攔收到這條數據,就斷開此客戶端的socket連接,返回socket值,根據返回的值確定此客戶端掉線了.
D. 為什麼基於TCP的應用需要心跳包
由於連接丟失時,TCP不會立即通知應用程序。比如說,客戶端程序斷肆灶線了,服務端的TCP連接不會檢測到斷線,而是一直處於連接狀芹衫態。這就帶來了很大的麻煩,比如明明客戶端已經斷了嫌雹腔,服務端還維護著客戶端的連接,照常執行著該玩家的游戲。
心跳包就是用來及時檢測是否斷線的一種機制,通過每間隔一定時間發送心跳數據,來檢測對方是否連接。是屬於應用程序協議的一部分。
E. java是否可以實現心跳的程序
java是可以實現心跳的程序的。
心跳顧名思義就是每隔一段時間執行,或者輪詢查詢狀態,可以使用timer來實卜晌乎現,代碼如下:
定時器可以實現
//1000毫秒型悉,固定時間,每隔1秒鍾執行一次actionPerformed方法
javax.swing.Timerclock=newjavax.swing.Timer(1000,new謹猜ActionListener(){
publicvoidactionPerformed(ActionEvente){
//執行心跳方法
/**...*/
//調用其他方法
/**...*/
}
});
clock.start();
可以獨立用個線程管理,也可以直接寫在主線程中
F. 高端推薦帖:回復:PLC心跳是什麼變數
PLC心跳一般是編程者編制的一個脈沖位,每間隔一段時間發一個脈沖。一般周期為1秒或者0.5秒。代表PLC正在運行。這個心並悉渣跳通常是用在兩個PLC系統通訊時其中一個系統判斷另外一陸臘個系統是否在正常運行絕悄。
G. 伺服器怎麼判斷心跳包
用sendUrgentData這個來判斷服務端是否異常關閉
想實現自動連接服務端,如果用
socket=鋒彎newSocket("192.168.1.4",1821);
socket.connect();
只有每次啟基州去new創建這個sock對象,因為只有sock對象創建好了才由輸入輸出流
目前的實現方式就是,
1.在原有的基礎上,再開多一個線程,專門負責發送心跳,
2.先睡眠500毫秒,
3.用socket.sendUrgentData(FF),給服務端,
4.如果服務端異常關閉的話,我就捕捉這個異常。。。
5.循環
心跳的意思就是每隔一段時間,客戶端給伺服器發一段消息:
1、客戶端:伺服器,我還活著,你死了沒
2、伺服器:客戶端,我知道你還活著這個信息,我已經記錄下來了,同時告訴你我也悄蔽還活著
更多問題到問題求助專區http://bbs.hounwang.com/
H. Socket心跳包機制總結
tcp的斷線檢測,分為兩種:
① 利用tcp自帶的keep –alive機制
② 自己組建心跳包的方式向對端發送
通過Keep-alive機制對tcp的連接保持,也就渣猛腔是Tcp的心跳包,見MSDN:
If keep-alive is enabled for a TCP socket with SO_KEEPALIVE, then the default TCP settings are used for the keep-alive timeout and interval unless these values have been changed by calling the WSAIoctl function with the SIO_KEEPALIVE_VALS option. The default settings when a TCP socket is initialized sets the keep-alive timeout to 2 hours and the keep-alive interval to 1 second.
也就是說協議棧會在2小時後發送向對端發送請求包。默認情況下,此Keep-alive機制是關閉的。
Keep-alive默認下是關閉的,也就是本端與對端是除非程序主動send,是不會發送數據包(心跳包),既是,處理本端與對端的系統里的socket狀態是不會變化,這里,如果對端當機(或者網線斷掉),本端是無法知道對端socket已經關閉,所以本端的socket會一直的存在。
通過實驗發現,客戶端網線拔掉之後,此時服務端的連接依然存在。
所以,tcp只是數據的發送與接收,包括握手,斷開以及rst,time_wait,close_wait 等等。
心跳包之所以叫心跳包是因為:它像心跳一樣每隔固定時間發一次,以此來告訴伺服器,這個客戶端還活著。事實上這是為了保持長連接,至於這個包的內容,是沒有什麼特別規定的,不過一般都是很小的包,或者只包含包頭的一個空包。
在TCP的機制裡面,本身是存在有心跳包的機制的,也就是TCP的選項:SO_KEEPALIVE。系統默認是設置的2小時的心跳頻率。但是它檢查不到機器斷電、網線拔出、防火牆這些斷線。而且邏輯層處理斷線可能也不是那麼好處理。一般,如果只是用於保活還是可以的。
心跳包一般來說都是在邏輯層發送空的echo包來實現的。下一個定時器,在一定時間間隔下發送一個空包給客戶端,然後客戶端反饋一個同樣的空包回來,伺服器如果在一定時間內收不到客戶端發送過來的反饋包,那就只有認定說掉線了。 其實,要判定掉線,只需要send或者recv一下,如果結如衫果為零,則為掉線。
但是,在長連接下,有可能很長一段時間都沒有數據往來。理論上說,這個連接是一直保持連接的,但是實際情況中,如果中間節點出現知乎什麼故障是難以知道的。更要命的是,有的節點(防火牆)會自動把一定時間之內沒有數據交互的連接給斷掉
。在這個時候,就需要我們的心跳包了,用於維持長連接,保活。
在獲知了斷線之後,伺服器邏輯可能需要做一些事情,比如斷線後的數據清理呀,重新連接呀……當然,這個自然是要由邏輯層根據需求去做了。
總的來說,心跳包主要也就是用於長連接的保活和斷線處理。一般的應用下,判定時間在30-40秒比較不錯。如果實在要求高,那就在6-9秒。
1、 客戶端每隔一個時間間隔發生一個探測包給伺服器
2、 客戶端發包時啟動一個超時定時器
3、 伺服器端接收到檢測包,應該回應一個包
4、 如果客戶機收到伺服器的應答包,則說明伺服器正常,刪除超時定時器
5、 如果客戶端的超時定時器超時,依然沒有收到應答包,則說明伺服器掛了