У вас уже есть хорошие ответы, но я думаю, что есть концепция, которую мы должны объяснить.
Когда вы отправляете данные через потоки (то есть что-то, что записывает количество байтов с одного конца, и эти байты могут быть прочитаны в том же порядке на другом конце), вы почти всегда хотите знать, когда прекратить чтение , Это обязательно, если вы отправите более одной вещи: когда первое сообщение останавливается, а второе начинается? В потоке вещи перепутаны.
Итак, как мы разграничиваем сообщения? Есть три простых способа (и, конечно, множество других, не очень простых):
1 Сообщения фиксированной длины :
Если вы заранее знаете, что каждое сообщение имеет длину, скажем, 10 байт, у вас нет проблем. Вы только что прочитали 10 байтов, и одиннадцатый будет частью другого сообщения. Это очень просто, но и очень жестко.
2 Разделительные символы или строки :
Если вы отправляете текст, читаемый человеком, вы можете разграничивать свои сообщения так же, как вы разграничиваете строки в ваших char*
: поставить символ 0 в конце. Таким образом, когда вы читаете 0, вы знаете, что сообщение закончилось, а все остальные данные в потоке принадлежат другому сообщению.
Это нормально для текста ascii, но когда дело доходит до произвольных данных, это также довольно жестко: есть символ или последовательность символов, которые ваши сообщения не могут содержать (или ваша программа запутается в том, где сообщение заканчивается).
3 Заголовки сообщений :
Это лучший подход для сообщений произвольной длины с произвольным содержимым. Перед отправкой любых фактических данных сообщения отправьте заголовок фиксированной длины (или используйте метод номер 2, чтобы отметить конец заголовка), указав метаданные о вашем сообщении. Например, это длина.
Скажем, вы хотите отправить сообщение «Круто», как вы сказали. Хорошо, сначала отправьте байт (или 2-байтовое короткое, или 4-байтовое целое число, или что-то еще), содержащий «4», длину сообщения, и получите его на другом конце. Вы знаете, что до того, как поступит какое-либо сообщение, вы должны прочитать 1 байт (или 2o, или 4, или что угодно), поэтому сохраните это где-нибудь и затем прочитайте оставшиеся указанные байты.
Очень простой пример:
struct mheader {
int length;
};
(...)
struct mheader in_h;
read(fd, &in_h, sizeof(struct mheader);
if (in_h.length > 0)
read(fd, buffer, in_h.length)
Надеюсь, это поможет. Удачи!