1.1 TCP和UDP的心跳包是用來維持長鏈接的html
心跳包只是用來檢測socket的連接狀態編程
2.1 非阻塞狀況下TCP 心跳包是否有必要創建心跳包網絡
須要,socket
a.若是說 嚴格 檢測掉線的話 那麼無論是否是非阻塞 都須要心跳包。(主要是由於心跳比較方便),若是想保持長鏈接,就須要按期發送心跳包tcp
b.函數
1). A和Z通訊。實際路線多是: A->b->c->d->...->Z。post
2). 後來,c和d有別扭,因而: A->b->c 「斷X了」 d->->Z。spa
3). 除非有超時機機制,不然recv函數不會知道c和d的分手的事。.net
3.1 TCP自帶心跳包定時爲2小時,是全局TCP心跳超時,會影響系統其餘應用網絡鏈接code
TCP有個KeepAlive開關,打開後能夠用來檢測死鏈接。一般默認是2小時,能夠本身設置。可是注意,這是TCP的全局設置。假如爲了能更及時的檢測出斷開的鏈接,把tcp_keepalive_time
和tcp_keepalive_intvl
的時間改小(參考:Link),該機器上全部應用程序的KeepAlive檢測間隔都會變小,顯然是不能接受的。由於不一樣應用程序的需求是不同的。
4.1 recv 返回值判斷鏈接狀況,
a. 返回0
阻塞接收的recv有時候會返回0,這僅在socket被正常關閉時纔會發生。
1) 正常關閉socket closesocket;
2)關機
b.返回-1
1) 阻塞,通常對於阻塞的socket都會用setsockopt來設置socket的超時。
當超時時間到達後,recv會返回錯誤,也就是-1,關閉重鏈接,無需心跳包
2) 掉線,斷網直接關閉程序
假設使用Socket基於TCP通訊協議進行C/S通訊編程,客服端已經成功與服務端創建tcp鏈接,而且能夠正常進行收發數據。
當一段時間後,服務端的程序若是調用closesocket(sClient);WSACleanup();函數關閉socket,
那麼客戶端的recv()將會返回0;
若是服務端沒有調用closesocket(sClient);而只調用WSACleanup();或直接關閉程序,
那麼客戶端的recv()將會返回-1(SOCKET_ERROR)。
以上結果在局域網通過實際驗證。
3)因爲終端信號,服務端返回-,可是客戶端依然鏈接,能發數據,怎麼辦? 心跳包重鏈接
其實,要斷定掉線,只須要send或者recv一下,若是結果爲零,則爲掉線。可是,在長鏈接下,有可能很長一段時間都沒有數據往來。理論上說,這個鏈接是一直保持鏈接的,可是實際狀況中,若是中間節點出現什麼故障是難以知道的。更要命的是,有的節點(防火牆)會自動把必定時間以內沒有數據交互的鏈接給斷掉。在這個時候,就須要咱們的心跳包了,用於維持長鏈接,保活。
5.1 心跳包超時時間20~40s適宜
4.1 附錄
https://www.zhihu.com/question/57736822
https://blog.csdn.net/qq_23167527/article/details/54290726
https://blog.csdn.net/liaomengge/article/details/50760831
https://www.zhihu.com/question/20849677/answer/16384522
https://www.cnblogs.com/nightwatcher/archive/2012/08/16/2643145.html
https://blog.csdn.net/tiandyoin/article/details/30044781
https://blog.csdn.net/baodi_z/article/details/43449315
http://www.nowamagic.net/academy/detail/23350382