Очистка буфера в сервере

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

Код сервера:

//server.cpp
#include <iostream>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
//#include <cstring>
#include <stdbool.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

//#define PORT 1234;

struct sockaddr_in local;

void ActiveServer(){
  int serv_sock = socket(AF_INET, SOCK_STREAM, 0);
  int client_sock;
  inet_aton("127.0.0.1", &local.sin_addr);
  int port = 1234;
  local.sin_port = htons(port);
  local.sin_family = AF_INET;
  bind(serv_sock, (struct sockaddr*) &local, sizeof(local) );
  listen(serv_sock, 5); // 5 -- сколько клиентов пытается соединиться
  //возвращает новый сокет, который связан с клиентом, который сделал коннект

  char buf[BUFSIZ];
  std::string str;
  ssize_t length = 0;
   while (true)
   {
      client_sock = accept(serv_sock, NULL, NULL); //принимаем соединение снаружи
      while ((length = read(client_sock, buf, BUFSIZ)) > 0){
        buf[length] = 0;
        str.append(buf);
        std::cout << str << std::endl;
        if((str.size() > 2) /*&& (std::stoi( str ) % 32 == 0)*/ ){
          std::cout << "Data received: " << buf[length] << std::endl;
        } else {
          std::cout << "Uncorrect data!" << std::endl;
          //exit(3);
        }
        str.clear();
      }
   }
}

int main(){
  ActiveServer();
  return 0;
}

Код клиента:

#include <iostream>
#include <algorithm>
#include <thread>
#include <mutex>

#include <string.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

std::mutex mtx;
struct sockaddr_in local;

void ReadString(std::string& str) {
    std::lock_guard<std::mutex> guard(mtx);
    //mtx.lock();
    //std::cout << "ID of 1st thread: " << std::this_thread::get_id() << std::endl;
    std::cin >> str;
    int arr[255]{};
    if (str.size() < 64) {
        //std::cout << str << std::endl;
        for (int i = 0; i < str.size(); i++) {
            if (isdigit(str[i])) {
                arr[i] = str[i] - 48;
            }
            else {
                std::cout << "The string contains not only numbers!" << std::endl;
            }
        }
    }
    else {
        std::cout << "The string is longer, than 64!" << std::endl;
        exit(1);
    }

    std::sort(std::begin(arr), std::end(arr), std::greater<int>());

    for (int i = 0; i < str.size(); i++) {
        if (arr[i] % 2 == 0) {
            str[i] = arr[i] + 48;
            str[i] = 'K';
        }
        else {
            str[i] = arr[i] + 48;
        }
    }
    for (int i = 0; i < str.size(); i++) {
        if (str[i] == 'K') {
            str.insert(i + 1, "B");
            i++;
        }
    }
    //mtx.unlock();
    //std::cout << str << std::endl;
}

int CountSum(std::string& str, int &sum) {
    std::lock_guard<std::mutex> guard(mtx);
    //std::cout << "ID of 2nd thread: " << std::this_thread::get_id() << std::endl;
    std::cout << str << std::endl;
    //int sum = 0;
    for (int i = 0; i < str.size(); i++) {
        if (isdigit(str[i])) {
            sum += str[i] - 48;
        }
    }
    return sum;
}

void CreateSocket(int &sum){
  int sock = socket (AF_INET, SOCK_STREAM, 0);
  inet_aton("127.0.0.1", &local.sin_addr);
  local.sin_port = htons(1234);
  local.sin_family = AF_INET;
  connect(sock, (struct sockaddr*) &local, sizeof(local));
  std::string tmp = std::to_string(sum);
  const char * buf = tmp.c_str();
  write(sock, buf, strlen(buf) + 1);
  close(sock);
}

int main()
{
    std::string arr;
    int sum = 0;
    while (true){
      std::thread ReadTh(ReadString, std::ref(arr));
      std::thread SumTh(CountSum, std::ref(arr), std::ref(sum));
      ReadTh.join();
      SumTh.join();
      CreateSocket(sum);
    }
}


Ответы (1 шт):

Автор решения: eri

Очистить буфер можно

memset(buf,0,BUFSIZ);

Ещё у Вас выводятся кусочки по буферам, а не сообщение целиком и они могут быть порезанны не так как на клиенте. Лучше бы изобрести протокол.

Хотябы TLV. Отправляешь байт типа сообщения, пока он один, но потом добавится всякое keep-alive. потом size_t длинна сообщения а дальше само сообщение.

На втором конце читаешь первый байт - уходишь в select-case. Читаешь длинну и вычитываешь сообщение в буфер пока полностью не дочитаешь указанную длинну.

→ Ссылка