C#异步TCP套接字:处理缓冲区的大小和巨大的转移 [英] C# Async TCP sockets: Handling buffer size and huge transfers
问题描述
当使用阻塞TCP套接字,我没有指定缓冲区大小。例如:
When using a blocking TCP socket, I don't have to specify a buffer size. For example:
using (var client = new TcpClient())
{
client.Connect(ServerIp, ServerPort);
using (reader = new BinaryReader(client.GetStream()))
using (writer = new BinaryWriter(client.GetStream()))
{
var byteCount = reader.ReadInt32();
reader.ReadBytes(byteCount);
}
}
请注意如何在远程主机才能发送任意多个字节。
Notice how the remote host could have sent any number of bytes.
不过,使用异步TCP套接字时,我需要创建C的最高大小的缓冲区,因此很难$ C $:
However, when using async TCP sockets, I need to create a buffer and thus hardcode a maximum size:
var buffer = new byte[BufferSize];
socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, callback, null);
我可以简单地将缓冲区大小,比方说,1024字节。这会工作,如果我只需要接收数据的小块。但是,如果我有什么需要获得10 MB的序列化对象?我可以设置缓冲区的大小为10 * 1024 * 1024 ...那会浪费一个恒定的10 MB的RAM,只要在应用程序运行。这是愚蠢的。
I could simply set the buffer size to, say, 1024 bytes. That'll work if I only need to receive small chunks of data. But what if I need to receive a 10 MB serialized object? I could set the buffer size to 10*1024*1024... but that would waste a constant 10 MB of RAM for as long as the application is running. This is silly.
所以,我的问题是:如何有效地利用异步TCP套接字接收数据的大块
推荐答案
两个例子是不等价的 - 你堵code假定端发送数据的32位长度的跟随。如果相同的协议是有效的异步 - 刚才读的长度(阻塞与否),然后分配缓冲区并启动异步IO
Two examples are not equivalent - your blocking code assumes the remote end sends the 32-bit length of the data to follow. If the same protocol is valid for the async - just read that length (blocking or not) and then allocate the buffer and initiate the asynchronous IO.
我还要补充一点的缓冲区分配用户输入,特别是中,网络输入,大小收据灾难。一个明显的问题是拒绝服务 攻击时,客户端请求一个巨大的缓冲,并持有到它 - 比如将非常缓慢的数据 - 而且prevents其他分配和/或减缓整个系统
Let me also add that allocating buffers of user-entered, and especially of network-input, size is a receipt for disaster. An obvious problem is a denial-of-service attack when client requests a huge buffer and holds on to it - say sends data very slowly - and prevents other allocations and/or slows the whole system.
共同智慧,一次是接受数据的固定量和解析,当您去。当然,这会影响你的应用层协议的设计。
Common wisdom here is accepting a fixed amount of data at a time and parsing as you go. That of course affects your application-level protocol design.
这篇关于C#异步TCP套接字:处理缓冲区的大小和巨大的转移的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!