С# Отправка размера объекта с сериализованным объектом через соединение с асинхронным сокетом

Я хочу сериализовать объект и отправить его по сети. Я настроил его с помощью атрибута ISerializeable в моем классе и BinaryFormatter для преобразования объекта в байты. Я могу отправить объект и десериализовать его на принимающей стороне. Однако, чтобы убедиться, что у меня есть весь объект, прежде чем пытаться его реконструировать, я хочу отправить размер вместе с потоком. Я хотел бы установить первые несколько байтов в качестве размера, проверить, когда полученные данные имеют по крайней мере этот фиксированный размер, тогда я могу прочитать это и получить полный размер объекта. Тогда это просто вопрос ожидания, пока мои полученные данные не будут размером объекта + байты фиксированного размера. Как я могу сместить свои данные в своем потоке, чтобы я мог отправить int для хранения размера объекта в виде первых нескольких байтов и моего объекта в качестве оставшихся байтов?


person Chris    schedule 03.11.2010    source источник
comment
О, пожалуйста. С вашим предыдущим вопросом (теперь удаленным) мы только что установили, что это была не (де) сериализация, а ввод-вывод.   -  person Henk Holterman    schedule 04.11.2010
comment
Я отправляю данные и закрываю поток. Затем я читаю из потока байт за байтом. В любой точке потока длина всегда равна одному байту. Мне нужно иметь возможность отправить длину, чтобы узнать, какова длина потока, и убедиться, что я получаю только один объект, а не части другого.   -  person Chris    schedule 04.11.2010
comment
Если ваш ввод-вывод правильный, Formatter позаботится о длине (ах)   -  person Henk Holterman    schedule 04.11.2010


Ответы (3)


Правильный ответ:

SocketPacket socketData = (SocketPacket)asyn.AsyncState;
socketData.currentSocket.EndReceive(asyn);
byte[] data = socketData.dataBuffer;   

неправильный способ чтения из SocketPacket?

person Henk Holterman    schedule 03.11.2010

Можете ли вы просто сериализовать в MemoryStream, а затем, как только это будет сделано, добавить .Length из MemoryStream, а затем данные (используйте GetBuffer() и скопируйте .Length байтов из массива). Реверс у приемника; прочитать длину (обычно 4 байта), затем упаковать столько данных в MemoeryStream; перемотать MemoryStream (Position=0) и десериализовать. Конечно, вам нужно согласовать порядок следования байтов и т.д.

(видите, и я даже не упомянул о защите... о, это другое)

person Marc Gravell    schedule 03.11.2010

Что именно вы пытаетесь предотвратить? TCP уже имеет встроенные проверки согласованности и надежности.

person Kent Boogaart    schedule 03.11.2010
comment
Мои мысли тоже ... Если только OP не отправляет UDP, но вы бы не стали этого делать, если бы надежность имела значение. - person Austin Salonen; 04.11.2010
comment
Я хочу убедиться, что все данные получены перед созданием моего объекта. Так как я читаю данные байт за байтом, и я не знаю, все ли данные были получены без установленного размера. - person Chris; 04.11.2010
comment
@Chris: В этом случае завершающие символы намного проще. - person Austin Salonen; 04.11.2010
comment
@Austin @Chris - с завершающими символами вам нужно анализировать данные по ходу, чтобы убедиться, что символ недействителен в контексте, например, как часть BLOB или Guid. Если цель состоит в том, чтобы просто буферизировать данные перед десериализацией, префикс длины является предпочтительным IMO. - person Marc Gravell; 04.11.2010
comment
@Остин, не могли бы вы привести пример. У меня есть пользовательский объект, и я не знаю, как добавить завершающий символ в поток. - person Chris; 04.11.2010
comment
@Marc Марк, в основном, мне нужен фиксированный префикс, содержащий длину. Как мне добавить это в поток, а затем прочитать со смещения, чтобы мой объект реконструировался правильно. - person Chris; 04.11.2010
comment
@Chris - вам не нужно читать со смещения; как только вы прочитали длину (обычно 4 байта), она ушла — просто прочитайте данные. Буферизация правильного объема данных в поток памяти позволяет избежать проблем с переполнением. - person Marc Gravell; 04.11.2010