咱們在調用recv(fd,buf,len,0)接口時,都要判斷返回值,若是返回值爲0,表示鏈路已斷開。然而若是len設置爲0,那麼返回值也是0,此時若是判斷鏈路斷開,顯然是不對的.在最近一次測試新功能的時候,測出了這樣一箇舊bug。追查bug的過程以下:web
爲了測試一個新功能,有這樣一個場景:A向B瘋狂的發送異步消息,其中B調用了個人接口。現象:B沒過多久發現recv()的返回值爲0,判斷鏈路斷開,而後嘗試重連A。這種高頻發送異步消息的場景我以前也是測試過的,是沒有問題的,只是沒有到達「瘋狂」的程度。這也致使我錯誤的認爲本身的代碼沒有問題,可以撐住高頻異步消息的場景,實際證實,我當時測試的「高頻」,還不夠高頻,因此沒有測出問題。編程
解決過程:發現B斷開連接以後,A和B的代碼邏輯中,都認爲是對方主動斷開,因而進行萬能的抓包。所幸A和B不在同一臺機器上面,不然還真抓不到,若是他們的通訊沒有通過網卡的話。抓包發現:B給A發了一個RST的數據包。這個包表明的含義以下:接收緩衝區有數據,主動斷開鏈路,就會給對方發送一個 RST 的包,說明異常斷開鏈接。這就是說,B的接收緩衝區裏面還有數據,可是B主動調用close(fd)函數斷開鏈路,此時A就會收到B發過來的RST的包。也就是說,鏈路是B主動斷開的。那麼問題來了,B爲什麼會主動斷開連接呢,明明B判斷是對方斷開鏈路,而後才斷開鏈路的啊?網絡
考慮到A瘋狂的發送異步消息,會不會是B的tcp接收緩衝區小了,沒法接受A發送的海量數據?可是將系統的tcp參數調整以後,發現問題依然存在。轉念一想,tcp接收緩衝區的大小,並不影響數據的接收,由於tcp有流量控制,利用滑動窗口的機制進行擁塞控制,若是B接收不了這麼多數據,A就會慢慢發,不會撐爆B的tcp緩衝區,致使鏈路斷開。異步
既然不是系統的緣由,那麼天然是代碼的緣由了。可是將代碼捋了幾遍以後,感受仍是沒問題。這也正常,畢竟,本身看本身的代碼,很難看出問題的。因而一個一個方向進行排查。tcp
首先考慮,是否是非網絡緣由致使的,好比線程/鎖等?想一想也不對,其餘線程沒有主動斷開鏈路的,可是我仍是作了一個測試,將recv()函數註釋掉,不去收數據了。這個結果天然是正常的,不會引起鏈路斷開,由於B不收數據,就不會判斷鏈路斷開,也就不會銷燬資源,同時也不會斷開鏈路。函數
看來問題仍是出在recv上面了。轉念一想,既然A和B都認爲本身沒有主動斷開鏈路,那麼是否是鏈路原本就是正常的,壓根就沒有斷開呢?因而我作了一個特殊處理,在B的邏輯中,若是B判斷鏈路異常,則忽略這個異常,繼續接收數據。果真,B能夠繼續接收數據,鏈路是正常的,B錯誤的判斷鏈路斷開!測試
獲得這個測試結果,我就更加納悶了,明明recv()函數的返回值爲0,表明鏈路斷開,查文檔都是這樣說的,爲啥到我這裏會這樣,那我豈不是沒法判斷鏈路究竟是正常仍是斷開?詢問同事以後,同事一句話令我茅塞頓開:recv(fd,buf,len,0)中的len若是設置爲0,返回值會是什麼狀況?還真有這個可能!我修改代碼,在recv以前先打印len的值,果真當len爲0時,recv的返回值也是0.緣由找到了!原來是在調用recv函數的時候,不能讓len設置爲0.spa
後記:其實在調用recv()函數以前,我是判斷過了len是否爲0的,只不事後來寫代碼的過程當中,中間加了其餘邏輯,修改過len的值,致使len有可能變爲0,然而我又沒有記起來,只記得本身判斷過len的值了.之後寫代碼仍是要注意,像這種值的判斷,儘可能寫在臨近調用的地方,防止本身修改過,而後又忘記了,還以爲本身已經處理過這種異常狀況。另外,對於網絡編程,多測試一下異常狀況,好比瘋狂發送。線程
檢測語言世界語中文簡體中文繁體丹麥語烏克蘭語烏茲別克語烏爾都語亞美尼亞語伊博語俄語保加利亞語僧伽羅語克羅地亞語冰島語加利西亞語加泰羅尼亞語匈牙利語南非祖魯語卡納達語印地語印尼巽他語印尼爪哇語印尼語古吉拉特語哈薩克語土耳其語塔吉克語塞爾維亞語塞索托語威爾士語孟加拉語宿務語尼泊爾語巴斯克語布爾語(南非荷蘭語)希伯來語希臘語德語意大利語意第緒語拉丁語拉脫維亞語挪威語捷克語斯洛伐克語斯洛文尼亞語斯瓦希里語旁遮普語日語格魯吉亞語毛利語法語波蘭語波斯尼亞語波斯語泰盧固語泰米爾語泰語海地克里奧爾語愛爾蘭語愛沙尼亞語瑞典語白俄羅斯語立陶宛語索馬里語約魯巴語緬甸語羅馬尼亞語老撾語芬蘭語苗語英語荷蘭語菲律賓語葡萄牙語蒙古語西班牙語豪薩語越南語阿塞拜疆語阿爾巴尼亞語阿拉伯語韓語馬其頓語馬爾加什語馬拉地語馬拉雅拉姆語馬來語馬耳他語高棉語齊切瓦語 |
|
世界語中文簡體中文繁體丹麥語烏克蘭語烏茲別克語烏爾都語亞美尼亞語伊博語俄語保加利亞語僧伽羅語克羅地亞語冰島語加利西亞語加泰羅尼亞語匈牙利語南非祖魯語卡納達語印地語印尼巽他語印尼爪哇語印尼語古吉拉特語哈薩克語土耳其語塔吉克語塞爾維亞語塞索托語威爾士語孟加拉語宿務語尼泊爾語巴斯克語布爾語(南非荷蘭語)希伯來語希臘語德語意大利語意第緒語拉丁語拉脫維亞語挪威語捷克語斯洛伐克語斯洛文尼亞語斯瓦希里語旁遮普語日語格魯吉亞語毛利語法語波蘭語波斯尼亞語波斯語泰盧固語泰米爾語泰語海地克里奧爾語愛爾蘭語愛沙尼亞語瑞典語白俄羅斯語立陶宛語索馬里語約魯巴語緬甸語羅馬尼亞語老撾語芬蘭語苗語英語荷蘭語菲律賓語葡萄牙語蒙古語西班牙語豪薩語越南語阿塞拜疆語阿爾巴尼亞語阿拉伯語韓語馬其頓語馬爾加什語馬拉地語馬拉雅拉姆語馬來語馬耳他語高棉語齊切瓦語 |
|
|
|
|
|