windows中命名管道讀寫buffer大小的設置問題


windows 管道機制為windows進程之間通信提供了方便快捷的方法,管道的創建方式和使用方法,搜索一下有很多!這里只解釋管道中buffer大小的設置問題!

函數源型:

HANDLE WINAPI CreateNamedPipe(
  _In_      LPCTSTR lpName,
  _In_      DWORD dwOpenMode,
  _In_      DWORD dwPipeMode,
  _In_      DWORD nMaxInstances,
  _In_      DWORD nOutBufferSize,
  _In_      DWORD nInBufferSize,
  _In_      DWORD nDefaultTimeOut,
  _In_opt_  LPSECURITY_ATTRIBUTES lpSecurityAttributes
);

這一塊msdn中解釋還是比較詳細的。

The pipe server should not perform a blocking read operation until the pipe client has started. Otherwise, a race condition can occur. This typically occurs when initialization code, such as the C run-time, needs to lock and examine inherited handles.

這個地方提到了阻塞,很多例子上面都會提示大家使用

nOutBufferSize=0;
 nInBufferSize=0;

如果dwPipeMode=PIPE_TYPE_BYTE 模式下
來實現阻塞式讀取,這個是不完全正確的,這個地方存在一個隱藏的bug。
設置成0並不是使用系統默認值,而是真的分配了0B的內存空間你或許會有疑問,那我為什么可以傳輸文件呢?
在MSDN中是這么說的:
 If the remaining pipe write quota is enough to fulfill the request, the write operation completes immediately. If the remaining pipe write quota is too small to fulfill the request, the system will try to expand the buffers to accommodate the data using nonpaged pool reserved for the process. The write operation will block until the data is read from the pipe so that the additional buffer quota can be released.
當空間不夠的時候 系統會擴大緩沖區以便來傳輸數據,並且會阻塞read進程執行直到數據被讀完之后才會釋放額外的空間,之后進程才會往下走。
如果此時你在read端是按一定字節大小讀取,並不是一次性讀完的。那么額外的空間此時沒有被釋放,但是又沒有全部被占用,write端是可以繼續寫的,就變成了一個有緩存機制的pipe通信,這樣數據就會讀錯!

如果在
dwPipeMode=PIPE_TYPE_MESSAGE

模式下基本不會出現上述問題
因為在此模式下會將每次輸出信息當成一個UNIT包來發送。
所以buffer大小設置范圍,要參考你要輸出的信息范圍最好是設置成最大可能消息長度。
如果要傳輸的信息特別大,比如說文件,那么你可以選擇多次發包,客戶端重新組合。這個地方就需要你去設計傳輸協議格式了!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM