如何处理从网络读取的缓冲数据?

发布于 2024-08-04 07:06:53 字数 464 浏览 5 评论 0原文

当通过网络读取数据时,您指定一个缓冲区来接收数据:

byte[] b = new byte[4096];
socket.Receive(b);

现在我的第一个想法当然是通过将其声明为类的成员变量来重用接收缓冲区。我的下一个问题是我没有收到我期望的所有数据,所以我需要缓冲我的数据。通过跟踪接收到的字节数并指定偏移量,这很容易完成:

socket.Receive(m_ReceiveBuffer, count, m_ReceiveBuffer.Length - count);

现在,这里的问题是,如果仍然不够,我猜测我需要增加缓冲区,这意味着复制内存,并继续接收到该缓冲区中。假设出现问题,该缓冲区将继续增长,如果接收到足够大的消息,则会导致系统内存不足。

有什么想法如何正确处理这个问题?有没有比我所说的填充、复制、增长、填充、复制、增长更好的接收数据的方法?

When reading data over the network, you specify a buffer to receive the data into:

byte[] b = new byte[4096];
socket.Receive(b);

Now my first thought is of course to reuse the receive buffer by declaring it as a member variable of the class. My next issue is that I have not received all of the data that I am expecting, so I need to buffer my data. This is easy to accomplish by keeping track of the count of bytes received, and specifying the offset:

socket.Receive(m_ReceiveBuffer, count, m_ReceiveBuffer.Length - count);

Now, the issue here is that if it is still not enough, I am guessing that I need to grow the buffer, which means copying memory, and continue to receive into this buffer. Assuming that something went wrong, this buffer would continue to grow, and if big enough messages are received, would run the system out of memory.

Any ideas how to properly handle this? Is there a better way of receiving the data than just fill, copy, grow, fill, copy, grow that I am talking about?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

烟酒忠诚 2024-08-11 07:06:53

分块读取:

const int ChunkSize = 4096;
int bytesRead;
byte[] buffer = new byte[ChunkSize];
while ((bytesRead = socket.Receive(buffer, 0, ChunkSize, SocketFlags.None)) > 0)
{
    byte[] actualBytesRead = new byte[bytesRead];
    Buffer.BlockCopy(buffer, 0, actualBytesRead, 0, bytesRead);
    // Do something with actualBytesRead, 
    // maybe add it to a list or write it to a stream somewhere
}

read in chunks:

const int ChunkSize = 4096;
int bytesRead;
byte[] buffer = new byte[ChunkSize];
while ((bytesRead = socket.Receive(buffer, 0, ChunkSize, SocketFlags.None)) > 0)
{
    byte[] actualBytesRead = new byte[bytesRead];
    Buffer.BlockCopy(buffer, 0, actualBytesRead, 0, bytesRead);
    // Do something with actualBytesRead, 
    // maybe add it to a list or write it to a stream somewhere
}
舟遥客 2024-08-11 07:06:53

在开始使用 SYstem.Net.Sockets.Socket 之前,您确定不能使用 System.Net.Sockets.TcpClient (或 UdpClient)来为您处理所有混乱的缓冲区并将其转换为易于管理的流吗?

如果不是,请记住您收到的数据量不必等于您请求的数据量,因此您应该始终查看 receive 函数的返回值。而且,不耗尽内存的唯一方法是实际处理您收到的内容。

Before starting with SYstem.Net.Sockets.Socket, are you sure that you can't use System.Net.Sockets.TcpClient (or UdpClient) that does all the messy buffer work for you and transforms it to an easily managed stream?

If not, remember that the amount of data you recieve doesn't have to be equal to what you request, so you should always look at the return value from the recieve function. And, the only way to not run out of memory is by actually processing what you recieve.

待天淡蓝洁白时 2024-08-11 07:06:53

首先,将代码分为接收数据和处理数据。接收缓冲区应该只保存数据,直到代码有机会将其复制到处理区域。处理区域是您确定是否已收到足够数据来执行有用操作的地方。在这种情况发生之前,不要将数据留在网络接收缓冲区中。对于网络接收缓冲区,我认为使用循环缓冲区将帮助您实现重用缓冲区的想法。希望您对消息大小有所了解。这将有助于确定缓冲区的大小。如果在循环缓冲区的读写指针相遇时断言(或类似的操作),则增加缓冲区的大小。一旦缓冲区的大小足够大,您应该能够以足够快的速率从缓冲区读取足够的数据到处理代码中,以使循环缓冲区不会溢出。

First, separate the code into receiving the data and processing the data. The receive buffer should only hold the data until the code gets a chance to copy it out to the processing area. The processing area is where you will determine if you have received enough data to do something useful. Don't leave the data in the network receive buffer until this happens. For the network receive buffer, I think using a circular buffer will help you with your idea of reusing a buffer. Hopefully, you have an idea of the message sizes. That will help in determining the size of the buffer. If you assert (or something similar) when the read and write pointers of the circular buffer meet, then increase the size of the buffer. Once the size of the buffer is large enough, you should be able to read enough data out of the buffer into the processing code at a rate fast enough that the circular buffer doesn't overflow.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文