如何在从TcpClient / NetworkStrem读取小数据时微调bufferSize? 如果bufferSize大到1024,4096读取/ 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);
}
答案 0 :(得分:2)
看起来像设置 ReadTimeout到1000,2000等值对阻塞没有影响。
Msdn说,使用异步BeginRead
方法时,ReadTimeout无效。
将bufferSize设置为1是否保证不会有任何块?
不,原因不是。当没有通过连接发送单个字节时,无论缓冲区大小如何,Read调用都将被阻塞。
性能影响会非常糟糕吗?
我猜你在这里谈论的是1字节缓冲区。
这取决于您收到的数据的数量和频率以及您在EndRead
上执行的代码。处理具有高带宽的流时,影响可能很大。您必须在接收数据时尝试观察您的cpu。
我不确定你想要分别达到你对阻塞的关注。
当您使用1024字节的缓冲区启动Receive(或Networkstream.Read),并且在套接字上接收10字节时,Read调用将在短暂延迟后返回10字节但不会阻塞直到整个缓冲区已填满。
还有其他方法可以缩短阻塞吗?
short 是什么意思?正如我所说,即使使用大缓冲区,Read也不会在接收少量数据时无休止地阻塞。
(NoDelay = true不起作用)
completely different这个故事可能很有意思,可以将你的发送方设置为true
(如果你也控制了它)。
当设置为false(默认值)时,它会将发送到较大数据块的小数据块组合起来,以减少一个tcp数据包(40字节标头)的开销。
修改强>
我的意思是如果没有数据,NetworkStream.BeginRead会立即返回。
使用stream.DataAvailable
怎么样?如果没有数据,它应该返回false。
此外,在使用异步模式时,如果有事情要做,那么调用是否会阻止预期的行为?否则,您将在繁忙的循环中进行活动轮询。
嗯,不敢相信。您通过频道发送了哪些数据?每分钟1个字节?每秒1000字节?当缓冲区很大时,它有时等待60秒返回(当它没有完全填满或填充到一定量时)