IOCP 零位元組緩衝解鎖疑問

2021-08-15 12:54:22 字數 1659 閱讀 2866

在開codeproject網上看乙個iocp的例子

在解決wsaenobufs問題的方法中,使用了投遞乙個使用零緩衝區的wsarecv來達到解鎖

作者網頁翻譯:wsaenobufs問題這個問題通常很難靠直覺發現,因為當你第一次看見的時候你或許認為是乙個記憶體洩露錯誤。假定已經開發完成了你的完成埠伺服器並且執行的一切良好,但是當你對其進行壓力測試的時候突然發現伺服器被中止而不處理任何請求了,如果你運氣好的話你會很快發現是因為wsaenobufs 錯誤而影響了這一切。 每當我們重疊提交乙個send或receive操作的時候,其中指定的傳送或接收緩衝區就被鎖定了。當記憶體緩衝區被鎖定後,將不能從物理記憶體進行分頁。作業系統有乙個鎖定最大數的限制,一旦超過這個鎖定的限制,那麼就會產生wsaenobufs 錯誤了。如果乙個伺服器提交了非常多的重疊的receive在每乙個連線上,那麼限制會隨著連線數的增長而變化。如果乙個伺服器能夠預先估計可能會產生的最大併發連線數,伺服器可以投遞乙個使用零緩衝區的receive在每乙個連線上。因為當你提交操作沒有緩衝區時,那麼也不會存在記憶體被鎖定了。使用這種辦法後,當你的receive操作事件完成返回時,該socket底層緩衝區的資料會原封不動的還在其中而沒有被讀取到receive操作的緩衝區來。此時,伺服器可以簡單的呼叫非阻塞式的recv將存在socket緩衝區中的資料全部讀出來,一直到recv返回 wsaewouldblock 為止。 這種設計非常適合那些可以犧牲資料吞吐量而換取巨大 併發連線數的伺服器。當然,你也需要意識到如何讓客戶端的行為盡量避免對伺服器造成影響。在上乙個例子中,當乙個零緩衝區的receive操作被返回後使 用乙個非阻塞的recv去讀取socket緩衝區中的資料,如果伺服器此時可預計到將會有爆發的資料流,那麼可以考慮此時投遞乙個或者多個receive 來取代非阻塞的recv來進行資料接收。(這比你使用1個預設的8k緩衝區來接收要好的多。) 原始碼中提供了乙個簡單實用的解決wsaenobuf錯誤的辦法。我們執行了乙個零位元組緩衝的非同步wsaread(...)(參見 onzerobyteread(..))。當這個請求完成,我們知道在tcp/ip棧中有資料,然後我們通過執行幾個有maximumpackagesize緩衝的非同步wsaread(...)去讀,解決了wsaenobufs問題。但是這種解決方法降低了伺服器的吞吐量。

總結: 

解決方法一: 

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

在投遞幾個普通含有緩衝區的receive操作後,進接著開始迴圈投遞乙個空緩衝區的receive操作。這樣保證它們按照投遞順序依次返回,這樣我們就總能對被鎖定的記憶體進行解鎖。 問題是:在客戶連入時觸發的oninitialize方法中,作者投遞了azerobyteread(pcontext,poverlapbuff);//零緩衝wsarecv

和幾個aread(pcontext)//有長度的wsarecv,那個零位元組的自然是解鎖了,可是有長度的解鎖了嗎?如果解鎖了是怎麼解的!

哪位高手解答一下!

解決方案 »

關於zero byte wsarecv(),具體自己看<>,看下適用環境和條件等,不要道聽途說。

在乙個連線上最好每次只投遞乙個wsarecv,不然會出現很多問題,比如資料報亂序問題。

知道原因了,樓上的全沒有答對,投遞乙個使用零緩衝區的wsarecv來達到解鎖所以關於該socket的快取全部解鎖

零位元組WSASend,WSARecv

以下是windows平台下兩個函式的宣告 int wsasend in socket s,in lpwsabuf lpbuffers,in dword dwbuffercount,out lpdword lpnumberofbytessent,in dword dwflags,int wsarecv...

位元,位元組,千位元組

如果你被人問到什麼是位元?什麼是位元組?這些網路中資料傳輸的單位一定會讓你有點毫無頭緒的感覺。沒關係,這些都很好理解,看過了下面的內容你就可以有條有理的把問題一一解答了。首先說說最小的單位,我們通常都叫做bit,也就是位元,有的時候也稱為位。但不管怎麼稱呼,他們都是二進位制數中最小的單位。單位的概念...

位元組對齊 8位元組對齊

參考博文 參考1 參考2 參考3 在記憶體管理中經常使用位元組對齊來管理分配的記憶體。1 原理 2 演算法 2.1unsigned intcalc align unsigned int n,unsigned align 2.2 更好的演算法 unsigned intcalc align unsign...