Очистка буфера в сервере
Есть клиент-серверное приложение, сервер получает от клиента строки и проверяет некоторые условия. Проблема в том, что данные не очищаются, и строки "склеиваются". Не могу сообразить, как почистить буфер, подскажите, пожалуйста
Код сервера:
//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 шт):
Очистить буфер можно
memset(buf,0,BUFSIZ);
Ещё у Вас выводятся кусочки по буферам, а не сообщение целиком и они могут быть порезанны не так как на клиенте. Лучше бы изобрести протокол.
Хотябы TLV. Отправляешь байт типа сообщения, пока он один, но потом добавится всякое keep-alive. потом size_t длинна сообщения а дальше само сообщение.
На втором конце читаешь первый байт - уходишь в select-case. Читаешь длинну и вычитываешь сообщение в буфер пока полностью не дочитаешь указанную длинну.