總會看到c++新手寫網(wǎng)絡(luò)通訊時,不理解recv()為什么阻塞或不阻塞,TCP數(shù)據(jù)順序會不會亂,UDP會不會數(shù)據(jù)包不完整,都是對TCP/IP協(xié)議原理沒有基本常識導(dǎo)致的。
我曾看到代碼,客戶端recv(buf, 31), 實際服務(wù)器只會發(fā)送4個字節(jié),客戶端將永遠阻塞,直到服務(wù)器主動close()為止。
開始時那個服務(wù)器是實現(xiàn)一請求一應(yīng)答,答應(yīng)后立即關(guān)閉,所以客戶端沒有事。
后來服務(wù)器維護者,感覺要支持一個連接上支持一個或多個請求,就修改成等待客戶端自己關(guān)閉或網(wǎng)絡(luò)異常,服務(wù)器才關(guān)閉socket。這個修改看來是正常的,因為服務(wù)器一般寫法都是被動關(guān)閉的,關(guān)閉權(quán)在客戶端。可是這么一修改,原來那個客戶端就阻塞死了,用戶莫名其妙。
這里有一個有趣現(xiàn)象:如果服務(wù)器維護者不修改,那么那個客戶端軟件一直是可以正常運行的,但從我們開發(fā)者角度來看,明明是一種實現(xiàn)錯誤,至少是缺陷吧??墒牵瑴y試人員黑盒測試是不可能測試出來的,一般測試人員也不會去寫代碼測試,所以這種問題測試組搞不定。
很多時候,在測試環(huán)境里沒問題,在真實環(huán)境就出現(xiàn)一些古怪的問題,其實問題不古怪。
比如:A通過TCP向B發(fā)送1024字節(jié),B采用一次性接收recv(buf, 1024), 測試環(huán)境常常每次都是一次收滿,包是完整的;在真實環(huán)境,A和B在不同地域,之間不知道多少交換機和路由器,那可能就第一次只收到500字節(jié),如果不加判斷返回值亂處理,問題就出來了。
這個問題還不止一次看到新手這么干。