Search code examples
cserverclientbuffercircular-buffer

Data exchange between Server and Client with Ring Buffer (Circular Buffer) in C


I wrote client-server chat for multiple clients (multiplexing i/o with non-blocking sockets).

Now I have fixed bufferSize (for example, length = 64). I want to make data exchange between client and server with Ring Buffer. I also wrote a few functions (buffer inisialisation, popFront and pushBack) to write into a buffer.

How is it possible to realize this idea? For example, I suppose I need 2 structures: the first structure has bufferlength and pointer to data in the other buffer, the second buffer has data. But now I have no idea what I should do with it. Could you give me an advice and maybe show with code? Thanks.

Here are my ringBuffer structures and function (I suppose the function bufferSize is wrong):

struct ringBuffer
{
    int *bufferData;
    int head;
    int tail;
    int size;
};

void bufferFree(struct ringBuffer *buffer)
{
    free(buffer->bufferData);
}

void bufferInitialization(struct ringBuffer *buffer, int size)
{
    buffer->size = size;
    buffer->head = 0;
    buffer->tail = 0;
    buffer->bufferData = (int*)malloc(sizeof(int) * size);
}

int pushBack(struct ringBuffer *buffer, int data)
{
    buffer->bufferData[buffer->tail++] = data;
    if (buffer->tail == buffer->size)
    {
        buffer->tail = 0;
    }
    return 0;
}

int popFront(struct ringBuffer *buffer)
{
    if (buffer->head != buffer->tail)
    {
        buffer->head++;
        if (buffer->head == buffer->size)
        {
            buffer->head = 0;
        }
    }
    return 0;
}

int bufferSize(struct ringBuffer *buffer)
{
    if (buffer->head >= buffer->tail)
    {
        return (buffer->head - buffer->tail);
    }
    else
    {
        return buffer->size - ((buffer->size - buffer->tail) + buffer->head);
    }
    /*for (int i = buffer->head; buffer->head < buffer->tail; i++)
    {
    printf("head[%d] and tail[%d] --> bufferData = %d", buffer->head, buffer->tail, buffer->bufferData);
    }*/
    return 0;
}

Solution

  • Basically, you need two things:

    1. A shared ring of pointers between your clients and server.
    2. A shared pool of buffers between your clients and server.

    There are a variety of flavors for the ring buffer: lockless, multi-consumer, multi-producer etc.

    Have a look at DPDK's ring library as an example or lockless rings. Here is a detailed description of algorithms: http://dpdk.org/doc/guides/prog_guide/ring_lib.html

    And here is the code: http://dpdk.org/browse/dpdk/tree/lib/librte_ring