Конкатенация буфера символов в строку - PullRequest
0 голосов
/ 21 января 2020

В следующем фрагменте я получаю данные, пока полностью не получу все данные от клиента сокета. Я продолжаю хранить данные в буфере символов размером 300.

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

}

Но проблема на каждой итерации, буфер пополняется, а старые значения теряются. Как объединить значения буфера в одно, чтобы в конце l oop я получил сообщение как одну полную строку?

Ответы [ 2 ]

1 голос
/ 22 января 2020

Вместо передачи buffer в recv(), передайте адрес следующего элемента buffer, который будет назначен, и накапливайте индекс, регулируя аргумент размера recv() для учета уже записанные данные:

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 ) ;


Если вместо простого заполнения буфера или тайм-аута вам необходимо использовать ограничитель, такой как \n, то вам нужно будет читать и проверять по одному символу за раз:

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 ) ;

Более полный пример функции сокета readline() можно найти, например, по адресу http://man7.org/tlpi/code/online/dist/sockets/read_line.c.html.

0 голосов
/ 21 января 2020

Вы можете сделать это что-то вроде следующего. Я предполагаю, что буфер не содержит строку.

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';  
}
...