С# поток получил все данные?

Я использую С#.Net и класс Socket из пространства имен System.Net.Sockets. Я использую методы асинхронного приема. Я понимаю, что это легче сделать с помощью чего-то вроде веб-сервиса; этот вопрос подтверждается моим любопытством, а не практической необходимостью.

Мой вопрос: предположим, что клиент отправляет некоторый двоично-сериализованный объект неизвестной длины. На моем сервере с сокетом, как я узнаю, что весь объект получен и что он готов к десериализации? Я рассмотрел возможность добавления объекта с длиной объекта в байтах, но это кажется ненужным в мире .Net. Что произойдет, если объект больше, чем буфер? Как я знаю, "эй, нужно изменить размер буфера, потому что объект слишком большой"?

Ответ 1

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

В случае протокола с автономным завершением вам нужно иметь достаточно крючков, чтобы код чтения мог узнать, когда он закончит. При двоичной сериализации вам может не хватить крючков. Префикс длины - это самое легкое решение здесь.

Ответ 2

Если вы используете чистые сокеты, вам нужно знать длину. В противном случае размер буфера не имеет значения, потому что даже если у вас есть буфер размера всех данных, он все равно может не читать все в нем - проверьте метод Stream.Read, он возвращает nr укусов, которые действительно читаются, поэтому вам нужно зациклиться до тех пор, пока не будут получены все данные.

Ответ 3

Да, вы не будете десериализовать, пока не будете все байты.