0

I am trying to add data received onto a buffer which needs to be configurable at runtime (I read a size from file or command line).

So basically I determine my buffersize and allocate an area of memory using calloc (I also put a catchall to set a buffersize if it is not in the config file or command line - Let's assume we use that for now).

I am only putting applicable lines of code.

int buffersize=10000;
void *BuffPtr = (void *)calloc(1,buffersize * sizeof(char));

I then have a recv from UDP (I have tried receiving into char array and dynamically allocated array - both work fine)

// Setup socket......

void *PktBuff = (void *)calloc(1,1000 * sizeof(char));

// Loop and receive many packets......

rcvd_bytes=recv(recv_socket, PktBuff, 1000, 0);

I can, at this point, write the contents of PktBuff and it works fine. But I want to concatenate a number of received packets in my dynamically allocated array (BuffPtr defined above).

I have tried strcat, but I just get garbage out if I try to write the first packet received, without getting another packet.

strcat(BuffPtr, PktBuff);

What I am doing wrong??

Thanks in advance.

3
  • strcat relies on '\0' as a string terminator. Try adding it after the strcat. Commented Oct 25, 2011 at 12:57
  • You're doing the calloc call wrong: The first argument is the number of items to allocate (buffersize in the first code chunk), and the second argument is the size of each items. It should be calloc(buffersize, sizeof(char)). Commented Oct 25, 2011 at 13:07
  • @BigMike errr no... that assumes BuffPtr is only comprised of non \0 bytes. Commented Oct 25, 2011 at 13:07

3 Answers 3

3

Your data doesn't seem to be 0-terminated strings, you may want to use memmove instead.

Sign up to request clarification or add additional context in comments.

6 Comments

Perhaps it could work reading in 999 bytes to PktBuff? As calloc zero inits the memory.
Or allocating 1001 bytes. That is if we assume, there are no zeros in the data.
Michael,I have tried memove it works for the first instance, then I get garbage for the second and subsequent packets.
Just be careful about what you moving where and make sure you have enough space to move things around.
OK, I have enough space, but still the same problem - My recv loop concatenates the first time, but the second time, only a single line of 'garbage' is added to the end of my dynamically allocated array - Or so it seems - The recv buffer holds the correct information, but memmove or memcpy just adds garbage. Any Ideas Please ?
|
2

A few points and observations:

  1. Don't cast the return value of malloc() in C.
  2. The expression sizeof (char) is a wordy way of writing 1, multiplying by it is seldom informative.
  3. Make sure all your data is 0-terminated (strings), otherwise you can't use string functions since that's what they require.
  4. You should probably just use an extra size_t counter to keep track of the number of bytes in BuffPtr, and use that and memcpy() to append.

1 Comment

Thanks, I do have a counter for the total bytes in BuffPtr, and following advice from Michael, I have used memove, which improves things marginally. I must be missing something like a terminating string on the packet ?? Will check.
0

Okay a number of issues in your code strcat is NOT the right way to append binary data. Here is a semi-robust implementation. I have NOT checked it for syntax errors, just typed it out please study it as an example, and adjust it to your code.

/* total number of bytes you are willing to receive in single a single receive */ 
#define MAX_RECV_BUFFER 1000

/* total number of bytes you are willing to store in memory */
#define MAXBYTES MAX_RECV_BUFFER*1000

int append_bytes() {
    char rcvbuf[MAX_RECV_BUFFER]; /* buffer where things are received */
    void *buf = NULL; /* buffer where bytes are collected */
    size_t rcvlen; /* length of data received */
    size_t buflen = 0; /* total bytes */

    while(1) {
         void *p;
         rcvlen = recv(recv_socket, rcvbuf, MAX_RECV_BUFFER, 0);
         if ( rcvlen < 0 ) { manage_error(); }
         if ( rcvlen == 0 ) 
                 break;
         if ( buflen + rcvlen > MAXBYTES) 
                 break;
         p = realloc(buf, buflen+recvlen);
         if ( !p ) { manage_memory_error(); }
         buf = p; /* we have enough space */
         memcpy(buf+buflen, rcvbuf, recvlen); /* append new content to end of buffer */
         buflen+=recvlen; /* add length to buflen */
    }      
}

1 Comment

Thanks, but the compiler doesn't like the memcpy. I have declared things exactly as you (removing my previous calloc) and get a compiler error referring to the buf+buflen argument in memcpy: expression must be a pointer to a complete object type ??????

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.