У вас уже есть хорошие ответы здесь, но я думаю, что есть концепция, которую мы должны объяснить.
Когда вы отправляете данные через потоки (то есть что-то, что записывает некоторое количество байтов с одного конца, и эти байты могут быть прочитаны в том же порядке с другого конца), вы почти всегда хотите знать, когда прекратить чтение. Это обязательно, если вы будете отправлять более одного сообщения: когда заканчивается первое сообщение и начинается второе? В потоке все смешивается.
Итак, как мы разграничиваем сообщения? Есть три простых способа (и много других, конечно, не таких простых):
1 Сообщения фиксированной длины. Если вы заранее знаете, что каждое сообщение имеет длину, скажем, 10 байт, то у вас нет проблем. Вы только что прочитали 10 байтов, а 11-й будет частью другого сообщения. Это очень просто, но и очень жестко.
2 символа-разделителя или строки. Если вы отправляете удобочитаемый текст, вы можете разделить свои сообщения так же, как вы разделяете строки в char*
: поставив в конце символ 0. Таким образом, когда вы читаете 0, вы знаете, что сообщение закончилось, а все оставшиеся данные в потоке принадлежат другому сообщению.
Это нормально для текста ascii, но когда дело доходит до произвольных данных, это также довольно жестко: есть символ или последовательность символов, которые не могут содержаться в ваших сообщениях (иначе ваша программа запутается в том, где заканчивается сообщение) .
3 заголовка сообщения: это лучший подход для сообщений произвольной длины и произвольного содержания. Перед отправкой любых фактических данных сообщения отправьте заголовок фиксированной длины (или используйте метод № 2, чтобы отметить конец заголовка), указав метаданные о вашем сообщении. Например, это длина.
Скажем, вы хотите отправить сообщение «Круто», как вы сказали. Ну, сначала отправьте байт (или 2-байтовый короткий, или 4-байтовое целое число, или что-то еще), содержащий «4», длину сообщения, и получите его на другом конце. Вы знаете, что прежде чем прибудет какое-либо сообщение, вы должны прочитать 1 байт (или 20, или 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)
Надеюсь, поможет. Удачи!
15.11.2010