вы правы, поток, полученный сокетом, может быть либо усеченным (принудительное отключение), либо, как вы видели, он может содержать дополнительные данные из другой операции отправки.
Вы можете поэкспериментировать с настройками сокета, чтобы указать немедленную отправку (nagle? Я думаю, это называется)
Благодаря работе, которую я проделал с TCP, у меня есть протокол связи, который используется для двоичных данных, и другой протокол, используемый для ascii. Когда я отправляю двоичные данные, у меня есть известные данные, с которых все коммуникации должны начинаться (BlockType (2 байта) BlockLength (4 байта) данных (нБайт))
Затем принимающая сторона знает, что нужно прочитать 6 байтов, чтобы определить тип и длину. Если я получаю менее 6 байт, попробуйте, пока я не сделаю и не буферизую предыдущие значения и т. Д., После того, как установленный размер станет известным, считайте, пока вы не прочитаете из данных байты BlockLength (буферизация по необходимости).
Если у вас отсоединено гнездо, вам нужно иметь дело с возобновлением или перезапуском и т. Д.
Если я работаю с данными ascii, я использую уникальный метод обтекания для блока передаваемых данных (~~~ start ~~~) .... DATA .... (~~~ end ~~~) чем просто буферизовать содержимое в строителе строк или аналогичном, пока вы не нажмете (~~~ end ~~~), а затем продолжите свои операции.
Надеюсь, это поможет.