完成埠中WSAENOBUFS錯誤的解決方案

2021-04-01 01:07:40 字數 1059 閱讀 3573

摘自csdn論壇

一、 wsaenobufs 錯誤問題。

這個問題通常很難靠直覺發現,因為當你第一次看見的時候你或許認為是乙個記憶體洩露錯誤。假定已經開發完成了你的完成埠伺服器並且執行的一切良好,但是當你對其進行壓力測試的時候突然發現伺服器被中止而不處理任何請求了,如果你運氣好的話你會很快發現是因為wsaenobufs 錯誤而影響了這一切。

每當我們重疊提交乙個send或receive操作的時候,其中指定的傳送或接收緩衝區就被鎖定了。當記憶體緩衝區被鎖定後,將不能從物理記憶體進行分頁。作業系統有乙個鎖定最大數的限制,一旦超過這個鎖定的限制,那麼就會產生wsaenobufs 錯誤了。

如果乙個伺服器提交了非常多的重疊的receive在每乙個連線上,那麼限制會隨著連線數的增長而變化。如果乙個伺服器能夠預先估計可能會產生的最大併發連線數,伺服器可以投遞乙個使用零緩衝區的receive在每乙個連線上。因為當你提交操作沒有緩衝區時,那麼也不會存在記憶體被鎖定了。使用這種辦法後,當你的receive操作事件完成返回時,該socket底層緩衝區的資料會原封不動的還在其中而沒有被讀取到receive操作的緩衝區來。此時,伺服器可以簡單的呼叫非阻塞式的recv將存在socket緩衝區中的資料全部讀出來,一直到recv返回 wsaewouldblock 為止。

這種設計非常適合那些可以犧牲資料吞吐量而換取巨大併發連線數的伺服器。當然,你也需要意識到如何讓客戶端的行為盡量避免對伺服器造成影響。在上乙個例子中,當乙個零緩衝區的receive操作被返回後使用乙個非阻塞的recv去讀取socket緩衝區中的資料,如果伺服器此時可預計到將會有爆發的資料流,那麼可以考慮此時投遞乙個或者多個receive來取代非阻塞的recv來進行資料接收。(這比你使用1個預設的8k緩衝區來接收要好的多。)

總結:解決方法一:

投遞使用空緩衝區的 recevie操作,當操作返回後,使用非阻塞的recv來進行真實資料的讀取。因此在完成埠的每乙個連線中需要使用乙個迴圈的操作來不斷的來提交空緩衝區的receive操作。

解決方法二:

在投遞幾個普通含有緩衝區的recevie操作後,進接著開始迴圈投遞乙個空緩衝區的recevie操作。這樣保證它們按照投遞順序依次返回,這樣我們就總能對被鎖定的記憶體進行解鎖。

完成埠模型

最近要做乙個網路方面的小東東,基於c s模式的。都說iocp可以使系統達到最佳的效能,因此我就比劃了兩下,獻醜了。抄書開始。從本質上說,完成埠模型要求建立乙個windows完成埠物件,該物件通過指定數量的執行緒,對重疊i o請求進行管理,以便為已經完成的重疊i o請求提供服務。首先要建立乙個i o完...

完成埠iocp和重疊埠

windows下的iocp和 linux下的epoll epoll我還沒有研究過 都是屬於socket 網路程式設計的範疇.不過其特色是 用固定很少的執行緒去管理成千上萬個socket連線.其相當於 非同步通訊 普通socket是同步,同步 可能要乙個執行緒乙個socket鏈結 去做,由於系統可以執...

完成埠的原理

完成埠 i o completion 非同步過程呼叫 apcs 問題 只有發完成埠 i o completion 的優點 不會限制 handle個數,可處理成千上萬個連線。i o completion port允許乙個執行緒將乙個請求暫時儲存下來,由另乙個執行緒為它做實際服務。併發模型與執行緒池 在...