My idea is to design and implement a efficient circular buffer to use with Socket server/client. I haven't seen this design anywhere. Its a bad ideia or something?
Here my initial design:
public class CircularBuffer
{
// Create IReadOnlyList for use
public IList<ArraySegment<Byte>> Buffers;
// Track memory
public int UsedMemory { get; private set; }
public int FreeMemory { get; private set; }
public int TotalMemory => UsedMemory + FreeMemory;
// Create buffer
public CircularBuffer(int memoryBlockSize = 512, int memoryBlockCount = 4);
// Add more blocks to circular buffer
public void IncreaseMemory(int memoryBlockSize = 512, int memoryBlockCount = 4);
// When using IList<ArraySegment<Byte>> we need know how much data is written
public void Advance(int count);
// Read n bytes and free segments
public byte[] Read(int count);
// Peek n bytes
public byte[] Peek(int count);
// Free n bytes without reading (useful with Peek())
public void Skip(int count);
}
Usage:
// Call BeginReceive of a Socket
Socket.BeginReceive(buffer.Buffers, SocketFlags.None, EndReceive, Socket);
// EndReceive method
private void EndReceive(IAsyncResult ar)
{
var socket = (Socket)ar.AsyncState;
var readedBytes = socket.EndReceive(ar);
buffer.Advance(readedBytes); // Our class need to know how much data is written on buffer
// This sample protocol use a 2byte header indicating the size of a incoming packet
while(buffer.UsedMemory > 2)
{
var header = buffer.Peek(2);
var messageSize = BitConverter.ToUInt16(header, 0);
if (buffer.UsedMemory - 2 < messageSize) break;
buffer.Skip(2);
var message = buffer.Read(messageSize);
// Here we process/dispatch our received packet
}
// If our buffer is full after last loop our packet is bigger than the current capacity
if(buffer.FreeMemory == 0)
{
buffer.IncreaseMemory();
}
// Start again
socket.BeginReceive(buffer.Buffers, SocketFlags.None, EndReceive, socket);
}
Aucun commentaire:
Enregistrer un commentaire