嵌入式开发之网络心跳包---阻塞和非阻塞以及是否有必要心跳包heartbeat
1.1 TCP和UDP的心跳包是用來維持長連接的
心跳包只是用來檢測socket的鏈接狀態
?
2.1 非阻塞情況下TCP 心跳包是否有必要建立心跳包
需要,
a.如果說 嚴格 檢測掉線的話 那么不管是不是非阻塞 都需要心跳包。(主要是因為心跳比較方便),如果想保持長連接,就需要定期發送心跳包
b.
1). A和Z通信。實際路線可能是: A->b->c->d->...->Z。
2). 后來,c和d有別扭,于是: A->b->c 「斷X了」 d->->Z。
3). 除非有超時機機制,否則recv函數不會知道c和d的分手的事。
3.1 TCP自帶心跳包定時為2小時,是全局TCP心跳超時,會影響系統其他應用網絡連接
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
?
總結
以上是生活随笔為你收集整理的嵌入式开发之网络心跳包---阻塞和非阻塞以及是否有必要心跳包heartbeat的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网易有道2017内推编程题
- 下一篇: 2016 EasyAR 开发者大会定档A