1

I'm implementing a server that receives a stream of bytes from the client.
The stream is serialized using msgpack, (and the first thing that is serialized is the length of the remaining stream).

My question is, What's the correct way of receiving this stream in C?
In python I can do this as follows:

# Feed each byte into the Unpacker
unpacker.feed(client.recv(1))
# Unpack whatever we can from the bytes we have received
for value in unpacker:
    print(value)

Is there a way I can do this in C?

Drxxd
  • 1,860
  • 14
  • 34
  • *"Is there a way I can do this in C?"* Way to do **what?** Are you asking us to write decoder for you? – user694733 Mar 01 '17 at 13:46
  • You probably need a structure, why are you doing it like this? – Iharob Al Asimi Mar 01 '17 at 13:52
  • I have a structure but the first thing I receive is the size of the whole buffer (Because I can receive different types of messages).. Anyway, what I'm asking is how can I receive and decode a stream using msgpack byte by byte (Like in the python script) – Drxxd Mar 01 '17 at 13:59
  • Can you post one of the inputs coming from the client? Using the python server you could do `print client.recv()`. It would help us understand your question better. – Ajay Brahmakshatriya Mar 01 '17 at 14:31

1 Answers1

1

I solved it, all I had to do is the following:

msgpack_unpacker tUnpacker = { 0 };
BOOL bUnpacked = FALSE;
unsigned char abReceivedBytes[1] = { 0 };
msgpack_unpacked tUnpacked = { 0 };
msgpack_unpack_return eUnpackRet = MSGPACK_UNPACK_PARSE_ERROR;

while (FALSE == bUnpacked)
{
    // Read here from socket
    ...

    /* Check buffer capacity and reserve more buffer if needed */
    if (msgpack_unpacker_buffer_capacity(&tUnpacker) < nNumOfBytes)
    {
        bResult = msgpack_unpacker_reserve_buffer(&tUnpacker, nNumOfBytes);
        if (FALSE == bResult)
        {
            // Handle error
        }
    }

    /* feeds the buffer. */
    memcpy(msgpack_unpacker_buffer(&tUnpacker), &abReceivedBytes[0], nNumOfBytes);
    msgpack_unpacker_buffer_consumed(&tUnpacker, nNumOfBytes);

    /* initialize the unpacked message structure */
    msgpack_unpacked_init(&tUnpacked);
    eUnpackRet = msgpack_unpacker_next(&tUnpacker, &tUnpacked);
    switch (eUnpackRet) {
    case MSGPACK_UNPACK_SUCCESS:
        /* Extract msgpack_object and use it. */
        bUnpacked = TRUE;
        break;
    case MSGPACK_UNPACK_CONTINUE:
        break;
    default:
        // Handle failure
        ...
    }

This is how you can read a stream using msgpack (This is almost equivalent to the python script in my question)

Drxxd
  • 1,860
  • 14
  • 34