Я хочу сериализовать объект и отправить его по сети. Я настроил его с помощью атрибута ISerializeable в моем классе и BinaryFormatter для преобразования объекта в байты. Я могу отправить объект и десериализовать его на принимающей стороне. Однако, чтобы убедиться, что у меня есть весь объект, прежде чем пытаться его реконструировать, я хочу отправить размер вместе с потоком. Я хотел бы установить первые несколько байтов в качестве размера, проверить, когда полученные данные имеют по крайней мере этот фиксированный размер, тогда я могу прочитать это и получить полный размер объекта. Тогда это просто вопрос ожидания, пока мои полученные данные не будут размером объекта + байты фиксированного размера. Как я могу сместить свои данные в своем потоке, чтобы я мог отправить int для хранения размера объекта в виде первых нескольких байтов и моего объекта в качестве оставшихся байтов?
С# Отправка размера объекта с сериализованным объектом через соединение с асинхронным сокетом
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
Мои мысли тоже ... Если только OP не отправляет UDP, но вы бы не стали этого делать, если бы надежность имела значение.
- person Austin Salonen; 04.11.2010
Я хочу убедиться, что все данные получены перед созданием моего объекта. Так как я читаю данные байт за байтом, и я не знаю, все ли данные были получены без установленного размера.
- person Chris; 04.11.2010
@Chris: В этом случае завершающие символы намного проще.
- person Austin Salonen; 04.11.2010
@Austin @Chris - с завершающими символами вам нужно анализировать данные по ходу, чтобы убедиться, что символ недействителен в контексте, например, как часть BLOB или Guid. Если цель состоит в том, чтобы просто буферизировать данные перед десериализацией, префикс длины является предпочтительным IMO.
- person Marc Gravell; 04.11.2010
@Остин, не могли бы вы привести пример. У меня есть пользовательский объект, и я не знаю, как добавить завершающий символ в поток.
- person Chris; 04.11.2010
@Marc Марк, в основном, мне нужен фиксированный префикс, содержащий длину. Как мне добавить это в поток, а затем прочитать со смещения, чтобы мой объект реконструировался правильно.
- person Chris; 04.11.2010
@Chris - вам не нужно читать со смещения; как только вы прочитали длину (обычно 4 байта), она ушла — просто прочитайте данные. Буферизация правильного объема данных в поток памяти позволяет избежать проблем с переполнением.
- person Marc Gravell; 04.11.2010