网络异常检查
從原理上分析,協(xié)議上,Socket連接使用的是TCP/UDP協(xié)議基于IP,Ping使用的是ICMP協(xié)議基于 IP。這就決定了兩者只是共用IP層。
只要網絡是通的,就可以機器間互相共享文件。如果是局域網上,任何單臺目標機器ping路由,ping本機都沒有問題也可以上網,則說明局域網是通的。(參考網絡編程經典《TCP/IP詳解》) 備注: 1、兩臺目標機器不在同一個網段是不能ping通的。若要能ping通,則需要路由器去路由轉發(fā),如將內網IP映射到一個公網IP或公網域名上(可以使用花生殼內網版客戶端)。
2、目標機器要能基于tcp/udp連接,必須要能互相ping通,但能ping通不一定就能connect上,可能訪問的端口不對,建議更換成正確的端口(如讓客戶端訪問服務端的內網端口映射到的外網端口)。 能順利ping通外網網址,說明你的計算機與外網網站是互通的。 之所以socket TCP連接失敗或者UDP無響應,原因可以從以下三個環(huán)節(jié)中查找: 1)本機(你的計算機) 防火墻是否屏蔽掉你使用的端口? 2)公司外網路由(或網關) 路由(網關)是否開放了你所指定的協(xié)議(TCP或UDP)以及端口? 3)外網網站 外網網站是否允許使用你所指定的協(xié)議(TCP或UDP)以及端口?上述三個環(huán)節(jié),只要有一個出問題,都會導致Socket連接失敗,或UDP無響應!
3、服務端和客戶端都運行在本地機器上,多個本地客戶端只能第一個客戶端去連接服務端才有效,即服務端只接收第一個本地客戶端的連接請求,后續(xù)第二個,第三個等本地客戶端的連接請求是不會再被接收的,會是個無響應的連接請求。而且這種服務端和客戶端都運行在本地機器上的情形,是不走網卡的。
?
?
?
下面是別處文章的內容:點擊打開鏈接
利用libevent進行網絡異常檢查(客戶端能及時檢測到自身的網絡異常)
《網絡編程釋疑之:TCP半開連接的處理》這篇文章主要講述了網絡異常的出現、以及如何在服務端解決存在的網絡異常。同時,客戶端能否及時檢測到自身的網絡異常(比如網絡禁用,網線斷開......)也同樣影響著客戶端的正常邏輯,下面我就通過自己的實驗和實踐來給大家說明下。
場景是這樣的,客戶端和服務端建立起一個長連接,并且通過一個心跳來維持上線狀態(tài)、同時也為了解決上面所說的TCP半開連接問題。客戶端在自身出現網絡異常的情況下下線,但是一旦自身網絡恢復要自動恢復此前的正常邏輯。這種情況在現實場景中有很多,比如底層協(xié)議為TCP的即時聊天軟件在自身網絡異常的情況下掉線,一旦網絡恢復就自動上線,還有其他很多的基于TCP自動重連應用。這樣,要求我們能及時快速的響應到網絡異常并開始新的自動重連動作。
當然,我們可以從操作系統(tǒng)的層次去迅速響應到網絡異常(比如網絡禁用,網線斷開...),但是我目前還沒找到特別好的方案,望有過實踐的朋友可以指導一二。我便退一步選用了在網絡應用層進行這種網絡異常的檢查,在這個過程中選用了libevent網絡庫的
void bufferevent_setcb (struct bufferevent *bufev, bufferevent_data_cb readcb, bufferevent_data_cb writecb, bufferevent_event_cb eventcb, void *cbarg)
方法,利用eventcb回調來響應網絡關閉或異常事件。之所以寫這篇文章,就是因為在這過程中發(fā)現了一些不同的網絡異常行為導致的處理不同,甚至在不同的操作系統(tǒng)下也有不同。
Windows系統(tǒng)
禁用網絡會立馬響應eventcb回調,對應的事件是BEV_EVENT_ERROR。
而斷開網線不會立馬響應eventcb回調,而是在下一次利用此socket進行數據操作時響應eventcb回調,對應的事件為BEV_EVENT_EOF。
Linux系統(tǒng)(CentOS)
禁用網絡和斷開網線都不會響應eventcb回調,需要自己去處理關閉socket描述符并清理響應libevent的資源。
Android系統(tǒng)
奇怪的是同是linux內核,但是在禁用網絡和wifi斷開情況下的處理卻和windows系統(tǒng)類似。
另外分享給大家一篇文章《網絡異常檢查》
總結
- 上一篇: 多线程执行CPU过高问题
- 下一篇: IP地址的三种表示格式 及 在Socke