問題描述:
近期在對新做的服務器做壓力測試時,發現服務端在接收一陣子數據之後便不再響應,不能接收新的連接,也不能接收新的數據。並且服務端接收到的數據個數非常有規律,每次都基本固定。
架構:
服務端基於select模型,測試客戶端爲socket client
問題查找:
1、最開始在沒有跟蹤代碼的情況下,先是懷疑服務端在收完數據後在處理過程中,由於某種原因產生了死鎖,檢查代碼後排除
2、程序中加入詳細日誌,觀察程序是死在了哪個地方。多次測試後發現,服務端在回覆客戶端多次後,在send時卡住了
3、思考send卡住的原因:會不會跟socket的緩衝區有關係?或者是有其它配置問題?
調試解決:
1、根據資料顯示,socket默認的發送緩衝大小爲8192字節,使用setsockopt修改緩衝區後,服務端收到數據的次數有明顯變化
int sbuflen = 8192*2;
setsockopt(ListenSocket, SOL_SOCKET, SO_SNDBUF, (const char*)&sbuflen, sizeof(int));
2、經分析,是由於測試客戶端沒有處理recv,服務端不斷send,導致send緩衝區變滿,從而卡死了send
3、測試客戶端加入對recv的處理後,問題解決
結論:
1、資料顯示socket的send緩衝區默認爲8192字節(8k),但是在實際測試中發現,send的數據在達到約23k時纔會卡死,爲什麼兩個值會有這麼大的差異,還需進一步覈實
2、不能單純的把緩衝區改大來解決該問題,要清楚爲什麼會滿
3、在socket編程中,特別是基於TCP的通信,要養成“一問一答”的好習慣,在保證通信數據完整性的同時,也避免了一些出問題的可能