網絡編程中常見錯誤碼總結

版權聲明:本文爲博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/cp3alai/article/details/51359986
在網絡編程中,總有各種需要注意的環節,幾乎每個API都要進行異常處理,判斷返回值以及錯誤碼來定位是否需要退出.
本文根據自身使用經驗,總結以下錯誤碼及其出現場景和一般處理流程.
網絡編程的一般性流程如下 :
客戶端 : socket -> connect -> write / read
服務端 : socket -> bind -> listen -> accept
還有因爲設置屬性帶來的其它改變,比如非阻塞和套接字選項.
EADDRINUSE : 如果你在同一個端口運行了無論是相同還是不同的程序,那麼bind就會出錯.即便是設置了SO_REUSEADDR,同一時刻也只允許同一個進程佔用指定端口,有一種極其特殊的情況,就是允許相同地址端口的完全重複綁定,但是這個特殊的情況需要傳輸協議支持,而且一般而言僅適用於UDP.(參考unp 7.5.11)
EINTR : 如果你並未對套接字設置非阻塞,那麼所有可能阻塞的函數都有可能遇到這個錯誤.比如connect,accept,read,write...等,面對這個錯誤,一般性的處理辦法是忽略掉它,繼續產生這個錯誤的操作.比如read一個套接字,如果遇到了這個錯誤,忽略掉,繼續read就行了.
EINPROGRESS : 一次connect的超時時間可能是75s左右(參考unp 4.3),有的時候我們並不想等待這麼長時間.有辦法,可以在調用connect之前設置套接字非阻塞,然後調用connect,此時connect會立刻返回,並且會設置errno爲EINPROCESS,這並不是一個致命錯誤,僅僅是告知你已經在連接了,你只要判斷是它就繼續執行後面的邏輯就行了,比如select.通過select設置超時來達到爲connect設定超時的目的.
ECONNABORT : 一個連接到來了以後,accept並不會立刻返回,而是先把這個連接放在未完成連接隊列,然後做一些處理以後放到已完成連接隊列,accept所做的只是從已完成連接隊列取這個連接而已,如果在accept取之前,連接異常斷開,accept就會返回這個錯誤,當然這個錯誤並不致命,但是如果你這樣寫,你就慘了
if (errno == EINTR/* || errno == ECONNABORT*/)
{
    continue;
}
else
{
    return -1;
上面這段代碼說明,當accept錯誤返回時,不僅要判斷中斷,還需要判斷連接終止.
EAGAIN : 如果你得套接字是非阻塞的,你需要對read/write/recv/send...等函數判斷返回值,如果其失敗返回,並且errno是EAGAIN,這並不致命,你只要忽略它,繼續處理就行,這個錯誤只是告訴我們,當前這個套接字並沒有數據可讀或者並沒有空間裝得下將要發送的數據.
EWOULDBLOCK : 在大多數的TCP實現中,這個錯誤碼和EAGAIN的意思是一樣的.參考百度百科 <errno >
ESRCH : 這個錯誤碼錶示的是進程或者線程不存在,當你在處理複雜的多進程或者多線程環境的時候,可以圍繞這個錯誤碼做很多事情.
ECONNRESET : 當我們調用connect連接服務器的時候,若服務器返回的是RST,我們就會收到這樣的錯誤.這看來算是一個致命的錯誤,如果遇到,要麼一直連,要麼就退出.
ETIMEDOUT : 如果你的套接字是阻塞的,你可能會在某個時間段內發不出數據,此時你就會收到ETIMEOUT
EHOSTUNREACH : 接上述場景,如果此時中間的某個路由器觸發ICMP對端不可達錯誤,那麼你的函數返回的錯誤碼就會是這個.
EPERM : 這個錯誤碼有點冷門了,我也是無意間遇到的.在編寫廣播程序的時候,如果採用了廣播地址,卻並未設置廣播屬性,就會出現這個errno
EPIPE 
: 這個錯誤應該是最複雜的一個錯誤了.我們首先需要了解的是在網絡編程中的一個特殊場景.
當一個套接字已經關閉了以後,如果我們繼續寫這個套接字,你並不會察覺有什麼異常,返回值告訴你,你寫成功了,但是如果通過wireshark抓包,你會發現,接收端回覆了一個RST,這個RST你根本就不知道.你唯一檢測它的辦法是讀一下這個套接字,此時會返回0,你才發現,原來連接已經斷開了.好吧,我假設我不管它,繼續寫,此時程序就會異常崩潰.是什麼導致了程序的崩潰呢,就是SIGPIPE,這個信號的默認行爲就是終止進程.
說回EPIPE,對於SIGPIPE,如果你沒有捕獲它,那麼程序也就退出了,也就談不上EPIPE了,所以,這個errno出現的前提一定是你設置了信號捕獲.那麼這個錯誤是否致命呢,看情況吧,反正連接也不在了,起碼拿到錯誤以後應該close掉本端的套接字.
以上...
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章