Да, вы правы - использовать available()
так, как это ненадежно. Лично я очень редко пользуюсь available()
. Если вы хотите читать, пока не достигнете конца потока (согласно заголовку вопроса), продолжайте вызывать read()
, пока он не вернет -1. Это легко. Сложность в том, что вам нужен не конец потока, а конец «того, что сервер хочет отправить вам в данный момент».
Как уже говорили другие, если вам нужно поговорить через сокет, вы должны заставить протокол объяснить, где заканчиваются данные. Лично я предпочитаю решение "длина префикса", а не решение "конец токена сообщения", где это возможно - обычно это делает код чтения намного проще. Однако это может затруднить написание кода , так как вам нужно определить длину перед отправкой чего-либо. Это боль, если вы могли бы посылать много данных.
Конечно, вы можете смешивать и сопоставлять решения - в частности, если ваш протокол работает как с текстовыми, так и с двоичными данными, я бы настоятельно рекомендовал бы использовать строки с префиксом длины, а не завершать их нулем (или что-то еще аналогичный). Декодирование строковых данных имеет тенденцию быть намного проще, если вы можете передать декодеру полный массив байтов и просто получить строку назад - вам не нужно беспокоиться о чтении, например, на половине пути символа. Вы можете использовать это как часть вашего протокола, но при этом иметь общие «записи» (или что-то, что вы передаете) с записью «конец данных», чтобы читатель мог обработать данные и ответить.
Конечно, все эти элементы дизайна протокола являются спорными, если вы не контролируете протокол: (