[英]Tuning buffer length for reading small data from NetworkStream
从TcpClient / NetworkStrem读取小数据时,如何微调bufferSize? 如果bufferSize大,如1024、4096,则Read / BeginRead块。 如果将bufferSize设置为16,则32不会阻塞。
看起来将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.