利用libevent進行網路異常檢查
《網路程式設計釋疑之:TCP半開連線的處理》這篇文章主要講述了網路異常的出現、以及如何在服務端解決存在的網路異常。同時,客戶端能否及時檢測到自身的網路異常(比如網路禁用,網線斷開......)也同樣影響著客戶端的正常邏輯,下面我就通過自己的實驗和實踐來給大家說明下。
場景是這樣的,客戶端和服務端建立起一個長連線,並且通過一個心跳來維持上線狀態、同時也為了解決上面所說的TCP半開連線問題。客戶端在自身出現網路異常的情況下下線,但是一旦自身網路恢復要自動恢復此前的正常邏輯。這種情況在現實場景中有很多,比如底層協議為TCP的即時聊天軟體在自身網路異常的情況下掉線,一旦網路恢復就自動上線,還有其他很多的基於TCP自動重連應用。這樣,要求我們能及時快速的響應到網路異常並開始新的自動重連動作。
當然,我們可以從作業系統的層次去迅速響應到網路異常(比如網路禁用,網線斷開...),但是我目前還沒找到特別好的方案,望有過實踐的朋友可以指導一二。我便退一步選用了在網路應用層進行這種網路異常的檢查,在這個過程中選用了libevent網路庫的
void
bufferevent_setcb (struct bufferevent *bufev, bufferevent_data_cb readcb, bufferevent_data_cb writecb, bufferevent_event_cb eventcb, void *cbarg)
方法,利用eventcb回撥來響應網路關閉或異常事件。之所以寫這篇文章,就是因為在這過程中發現了一些不同的網路異常行為導致的處理不同,甚至在不同的作業系統下也有不同。
Windows系統
禁用網路會立馬響應eventcb回撥,對應的事件是BEV_EVENT_ERROR
。
而斷開網線不會立馬響應eventcb回撥,而是在下一次利用此socket進行資料操作時響應eventcb回撥,對應的事件為BEV_EVENT_EOF
。
Linux系統(CentOS)
禁用網路和斷開網線都不會響應eventcb回撥,需要自己去處理關閉socket描述符並清理響應libevent的資源。
Android系統
奇怪的是同是linux核心,但是在禁用網路和wifi斷開情況下的處理卻和windows系統類似。