- 减少了ToArray() 的复制操作(包已完整,获取包数据时)
- 减少了GetRange() 的复制操作(当需要获取到头部4字节判断包长度时)
代码
C#
public class ReceiveDataBuffer
{
private Memory<byte> items { get; set; } = Helper.EmptyArray.AsMemory();
private int size = 0;
public int Size
{
get
{
return size;
}
private set
{
if (value == 0)
{
items = Helper.EmptyArray;
}
else if (value > items.Length)
{
Memory<byte> newItems = new byte[value].AsMemory();
items.CopyTo(newItems);
items = newItems;
}
}
}
public Memory<byte> Data
{
get
{
return items;
}
}
public void AddRange(Memory<byte> data, int length)
{
BeResize(length);
data.Slice(0, length).CopyTo(items.Slice(size, length));
size += length;
}
public void AddRange(byte[] data, int offset, int length)
{
BeResize(length);
data.AsMemory(offset, length).CopyTo(items.Slice(size, length));
size += length;
}
public void RemoveRange(int index, int count)
{
if (index >= 0 && count > 0 && size - index >= count)
{
size -= count;
if (index < size)
{
items.Slice(index + count, size - index).CopyTo(items.Slice(index, size - index));
}
}
}
public void Clear(bool clearData = false)
{
size = 0;
if (clearData)
{
Size = 0;
}
}
private void BeResize(int length)
{
int _size = size + length;
if (_size > items.Length)
{
int newsize = items.Length * 2;
if (newsize < _size)
{
newsize = _size;
}
Size = newsize;
}
}
}
使用示例
C#
ReceiveDataBuffer buffer = new ReceiveDataBuffer();
byte[] bytes = new byte[8*1024];
while(true)
{
//从网络接收到数据
int length = socket.ReceiveAsync(bytes);
if (length == 0)
{
break;
}
//将网络数据添加到缓存中
buffer.AddRange(bytes, length);
do
{
//0-4字节是包长度内容
int packageLen = BitConverter.ToInt32(buffer.Data.Span);
if (packageLen > buffer.Size - 4)
{
break;
}
Memory<byte> data = buffer.Data.Slice(4, packageLen);
//拿data去随便干啥
//删除已使用的数据
buffer.RemoveRange(0, packageLen + 4);
} while (buffer.Size > 4);
}