2017-01-16 2 views
2

Как сохранить соединение с подключенным клиентом? В приведенном ниже коде поток получает данные и отвечает клиенту и отключается. Я хочу поместить процесс получения и отправки в цикле. Как я могу это сделать ?Как получать и отправлять данные с сервера клиенту в цикле

void *thread_handle_connection(void *arg) { 
    char buffer[MAX_MSG_SIZE]; // Receive buffer 
    int bytes_read; 

    do { 

    // If there aren't any connections, sleep and recheck every second 
    while(!num_connections && !term_requested) { 
     sleep(1); 
    } 

    // Lock out connections queue and grab the first one 
    pthread_mutex_lock(&queue_mutex); 
    int connectionfd = remove_connection_from_queue(); 
    pthread_mutex_unlock(&queue_mutex); 

    if(-1 == connectionfd) { 
     continue; 
    } 

    // pthread_barrier_wait(&barrier); // Barrier for threads - for testing only 

    // Read up to 1024 bytes from the client 
    bytes_read = recv(connectionfd, buffer, MAX_MSG_SIZE - 1, 0); 

    // If the data was read successfully 
    if(bytes_read > 0) { 
     // Add a terminating NULL character and print the message received 
     buffer[bytes_read] = '\0'; 

     // Calculate response 
     int multiplicand = atoi(buffer); 
     char *response; 
     asprintf(&response, "%d", multiplicand * MULTIPLIER); 

     // Echo the data back to the client; exit loop if we're unable to send 
     if(-1 == send(connectionfd, response, strlen(response), 0)) { 
     warn("Unable to send data to client"); 
     break; 
     } 
     free(response); 
    } 

    // Close connection 
    close(connectionfd); 

    } while(bytes_read > 0 && !term_requested); 

    return NULL; 
} 
+1

Что именно вы спрашиваете? – zmbq

+2

Хорошо, чтобы обернуть полученный код в реальном цикле было бы хорошим началом. Затем просто прочитайте и напишите в этом цикле до тех пор, пока не появится ошибка или соединение не будет закрыто. –

ответ

0

Во-первых, recv функция не гарантирует, что вы читали все, что было написано отправителем. Вы можете получить часть данных (например, отправитель может отправить 10KByte, но получатель может получить только 1.5K при первом чтении).

Во-вторых, send Функция не гарантирует, что она отправит все, что вы просите. Если не все отправлено, вам нужно отправить остальную часть ответа.

В-третьих, TCP ориентирован на поток. Это означает, что вам нужно отделить одно сообщение от другого. Для текстового протокола для этой цели используется «новая строка».

Взяв все вместе. Если вы хотите, постоянное соединение с запросом вам необходимо:

  • определяет запрос и ответ сепараторы
  • поддерживать буфер чтение
  • прочитать все данные в буфер и сканирование для запроса сепаратора
  • ответа посыла с сепаратором ответа

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

Смежные вопросы