1

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

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

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

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

现在,这里的问题是,如果还不够,我猜我需要增加缓冲区,这意味着复制内存,并继续接收到这个缓冲区。假设出现问题,这个缓冲区会继续增长,如果收到足够大的消息,系统就会内存不足。

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

4

3 回答 3

2

分块阅读:

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
}
于 2009-09-10T08:24:34.653 回答
1

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

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

于 2009-09-10T08:25:07.510 回答
0

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.

于 2009-09-11T21:21:19.240 回答