Как немедленно отправить конкретную порцию данных. Сокет C

Рейтинг: 0Ответов: 1Опубликовано: 15.05.2023

Есть сервер и есть клиент по передаче файлов, и там и там буфер для записи/чтения по 1450 байт.

Когда сервер отправляет последние данные файлы, клиент должен записать их в файл, а после, вывести сообщение о том, что загрузка прошла успешно (это сообщение тоже отправляет сервер, так же сервер отправляет еще одно сообщение - о доступных командах (меню)). В общем сервер работает через состояния. Я перечислил 3 из них:

  1. отправка файла, пока файл не кончился (пока чтение из него по 1450 байт);
  2. отправка сообщения об успешном завершении (когда последнее чтение было меньше 1450 байт, сервер меняет состояние клиента на 2);
  3. отправка списка доступных команд (переход сюда, когда 2 было отправлено).

Проблема: сервер объединяет всё и отправляет разом (последние данные файла + сообщение об успехе + список доступных команд). Как мне сделать так, что бы сокет отправлял данные СРАЗУ, не накапливая сообщения в своем буфере?

UPD:

Условный код сервера (sc - client):

send(sc, "asd", 3, 0);
send(sc, "zxc", 3, 0);

Условный код клиента (ss - server):

recv(ss, buf, 1450, 0);
// что-то делаем + чистим буфер
recv(ss, buf, 1450, 0);
// что-то делаем

Первый вызов recv примет сразу "asdzxc", как их наверняка разделить? Что бы на первый recv пришел только asd, а на второй zxc. Может есть какие-то флаги для сокетов и их функций на подобные случаи? Пытался найти ответ в манах socket, send и recv, но ничего подобного там не увидел :(

UPD2:

Тип сокета - SOCK_STREAM

UPD3:

Вопрос решен в комментариях.

Ответы

▲ 1

Для разделения данных на пакеты обычно используются протоколы высокого уровня.

Самый распространенный это структуры TLV. Сервер отправляет тип данных (например один байт), длинну передачи, а затем сами данные.

код клиента будет выглядеть примерно так.

while (1) {
  recv(ss, &t, 1, 0);
  if (t != 'd') break или continue или process = process_data;
  recv(ss, &l, 2, 0);
  recv(ss, buf, l, 0);
  process(buf, l);
}