簡體   English   中英

調整緩沖區長度以從NetworkStream讀取小數據

[英]Tuning buffer length for reading small data from NetworkStream

從TcpClient / NetworkStrem讀取小數據時,如何微調bufferSize? 如果bufferSize大,如1024、4096,則Read / BeginRead塊。 如果將bufferSize設置為16,則32不會阻塞。

  • 將bufferSize設置為1是否可以確保沒有任何塊? 性能影響會很差嗎?
  • 看起來將ReadTimeout設置為1000、2000之類的值不會對阻塞產生影響。 還有其他方法可以縮短封鎖時間嗎? (NoDelay = true不起作用)

     public static IObservable<byte[]> AsyncReadChunk(this Stream stream, int bufferSize) { var buffer = new byte[bufferSize]; return Observable.FromAsyncPattern<byte[], int, int, int>(stream.BeginRead, stream.EndRead)(buffer, 0, bufferSize) .Select(cbRead => { var dataChunk = new byte[cbRead]; Buffer.BlockCopy(buffer, 0, dataChunk, 0, cbRead); return dataChunk; }); } public static IObservable<byte[]> AsyncRead(this NetworkStream stream, int bufferSize) { return Observable.Defer(() => stream.DataAvailable ? AsyncReadChunk(stream, bufferSize) : Observable.Return(new byte[0])) .Repeat() .TakeWhile((dataChunk, index) => dataChunk.Length > 0); } 

看起來將ReadTimeout設置為1000、2000之類的值不會對阻塞產生影響。

Msdn說,使用異步BeginRead方法時,ReadTimeout無效。

將bufferSize設置為1是否可以確保沒有任何塊?

不,原因不對。 如果沒有通過連接發送單個字節,則無論緩沖區大小如何,Read調用都會阻塞。

性能影響會很差嗎?

我猜您在這里談論的是1字節緩沖區。 這取決於您收到的數據的數量和頻率以及在EndRead執行的代碼。 在處理具有高帶寬的流時,影響可能很大。 您必須嘗試在接收數據時觀察CPU。

我不太確定您要分別實現什么,而您對阻塞的關注是什么。

當您啟動一個具有例如1024個字節的緩沖區的Receive(或Networkstream.Read),並且在套接字上收到10個字節時,Read調用將在短暫的延遲后返回該10個字節,但是直到整個緩沖區被填滿后才會阻塞。

還有其他方法可以縮短封鎖時間嗎?

簡而言之你什么意思。 如我所說,即使有很大的緩沖區,當接收少量數據時,讀取也不會無限阻塞。

(NoDelay = true不起作用)

那是一個完全不同的故事,但是在發件人一側將它設置為true可能會很有趣(如果您也可以控制的話)。

設置為false(默認值)時,它將把發送的較小數據塊合並為較大的數據塊,以減少一個tcp數據包(40字節標頭)的開銷。

編輯

我的意思是NetworkStream.BeginRead如果沒有數據,則立即返回。

關於使用stream.DataAvailable呢? 沒有數據時應返回false。

另外,在使用異步模式時,不是在某些事情要做之前調用將被阻塞的預期行為嗎? 否則,您將在繁忙的循環中獲得主動輪詢。

當緩沖區很大時,有時會等待60秒返回(當緩沖區未完全填充或填充到一定量時)

嗯,真不敢相信。 您通過通道發送什么樣的數據? 每分鍾1個字節? 每秒1000個字節?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM