Concatenating char buffer into a string

2020-05-07 06:34发布

问题:

In the following snippet, I receive the data until I have completely received all the data from the socket client. I keep on storing the data in a char buffer of size 300.

ssize_t b;
char buffer[300]
while((b = recv(socket_fd,buffer,sizeof(buffer))) > 0) {
   // keep on receiving the data

}

But the problem is on each iteration, buffer gets refilled and old values are lost. How do I concatenate the buffer values into one, so that at the end of the loop I get the message as one complete string?

回答1:

You can do this something like the following. I assume that buffer does not contain a string.

ssize_t b;
char buffer[300]
size_t n = 1;
char *s = calloc( 1, sizeof( char ) );

while((b = recv(socket_fd,buffer,sizeof(buffer))) > 0) {

    char *tmp = realloc( s, b + n );

    if ( !tmp )
    {
        // report an error
        break;
    }

    s = tmp;
    memcpy( s + n - 1, buffer, b );
    n += b;
    s[n - 1] = '\0';  
}


回答2:

Rather than passing buffer to recv(), pass the address of next element of buffer to be assigned and accumulate an index, adjusting the size argument of recv() to account for the data already written:

char buffer[300] ;
ssize_t buffer_index = 0 ;
ssize_t chunk = 0 ;

do 
{
   chunk = recv( socket_fd, 
                 &buffer[buffer_index], 
                 sizeof(buffer) - buffer_index - 1 ) ;

   if( chunk > 0 )
   {
       buffer_index += chunk ;
       buffer[buffer_index] = '\0' ;
   }

} while( buffer_index < sizeof(buffer) - 1 && 
         chunk > 0 ) ;


If rather then simply filling the buffer or timing out you need to terminate on a delimiter such as \n then you will need to read and inspect one character at a time:

char buffer[300] ;
ssize_t buffer_index = 0 ;
ssize_t status = 0 ;

do 
{
   status = recv( socket_fd, 
                  &buffer[buffer_index], 
                  1 ) ;

   if( status > 0 )
   {
       buffer_index++ ;
       buffer[buffer_index] = '\0' ;
   }

} while( ch != '\n' && 
         buffer_index < sizeof(buffer) - 1 && 
         status > 0 ) ;

A more complete example of a socket readline() function can be found at http://man7.org/tlpi/code/online/dist/sockets/read_line.c.html for example.