473,787 Members | 2,931 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Getting serilized data size

Using the below code I am send multiple sterilized object across an IP port.
This works fine if only one object is received at a time but with packing
sometimes there is more then one object or half an object in the received
data. If I place the data in a memory stream on the received side is there
a way to determine where one ends and the next one start?

Since the deserializer stream seems to move the pointer I am trying to look
at the next couple bytes to determine if there is more data in the stream.
It seems that serialized data starts with 0,1 but I can not confirm this.
Is there maybe a rule?

I have also noticed that the number of bytes recieved is always bigger then
the number of bytes deserizlized, any clue why?

CODE 1
IFormatter f = new BinaryFormatter ();
MemoryStream ms = new MemoryStream();
f.Serialize(ms, cmd);
byte[] b = ms.GetBuffer();
this.socket.Beg inSend(b, 0, b.Length, SocketFlags.Non e, new
AsyncCallback(S end_Callback), this.socket);

CODE 2
IFormatter i = new BinaryFormatter ();
MemoryStream ms = new MemoryStream(o, 0, len);
ms.Position = 0;
while(ms.Positi on < len)
{
long position = ms.Position;
if(!(ms.ReadByt e() == 0 && ms.ReadByte() == 1))
break;
ms.Position = position;

object obj = i.Deserialize(m s);
.....

Regards,
John
Nov 16 '05 #1
14 2276
John,

How are you getting the value of "len" in CODE 2? Did you try looking at
ms.Length after serialization? Maybe you could send that in some sort of
delimited fashion over the wire.

- SM
"John J. Hughes II" <no@invalid.com > wrote in message
news:Ou******** ******@TK2MSFTN GP15.phx.gbl...
Using the below code I am send multiple sterilized object across an IP
port. This works fine if only one object is received at a time but with
packing sometimes there is more then one object or half an object in the
received data. If I place the data in a memory stream on the received
side is there a way to determine where one ends and the next one start?

Since the deserializer stream seems to move the pointer I am trying to
look at the next couple bytes to determine if there is more data in the
stream. It seems that serialized data starts with 0,1 but I can not
confirm this. Is there maybe a rule?

I have also noticed that the number of bytes recieved is always bigger
then the number of bytes deserizlized, any clue why?

CODE 1
IFormatter f = new BinaryFormatter ();
MemoryStream ms = new MemoryStream();
f.Serialize(ms, cmd);
byte[] b = ms.GetBuffer();
this.socket.Beg inSend(b, 0, b.Length, SocketFlags.Non e, new
AsyncCallback(S end_Callback), this.socket);

CODE 2
IFormatter i = new BinaryFormatter ();
MemoryStream ms = new MemoryStream(o, 0, len);
ms.Position = 0;
while(ms.Positi on < len)
{
long position = ms.Position;
if(!(ms.ReadByt e() == 0 && ms.ReadByte() == 1))
break;
ms.Position = position;

object obj = i.Deserialize(m s);
....

Regards,
John

Nov 16 '05 #2
John J. Hughes II wrote:
Using the below code I am send multiple sterilized object across an IP port.
This works fine if only one object is received at a time but with packing
sometimes there is more then one object or half an object in the received
data. If I place the data in a memory stream on the received side is there
a way to determine where one ends and the next one start?


Through _painstaking_ tracing and hours of debugging thinking that a
network card driver was buggy, I have found that:

- The SoapSerializer. Deserialize (sometimes) read more data than
SoapSerializer. Serialize generates (due to buffered reads).

- The BinarySerialize r.Deserialize doesn't always read all the data
generated by BinarySerialize r.Serialize, and will Close() the stream
when done deserializing!

So basically, you cannot send multiple serialized objects down the same
stream without being really lucky, especially after .NET-sp1.
SoapSerializer used to work most of the time before .NET-sp1.

My solution for sending multiple serialized objects, in a streaming way,
inside the same trasport-Stream is to implement a Stream that does
chunk-length en/de-coding of the amount of data written.

So I have a BlockSubStreamW riter, that writes a 16-bit length and then
the data to be written to the stream, and writes a 16-bit 0-length and
flushes to mark Close(), and a BlockSubStreamR eader that reads 16-bit
length and then corresponding data, making EOF if the length is 0, and
"eating" the rest of stream untill a 0-length is received if the
BlockSubStreamR eader is Close() or Dispose()'ed without having read a
0-length.

So now i can say

new BinarySerialize r.Serialize(new BlockSubStreamW riter(stream), graph);
new BinarySerialize r.Deserialize(n ew BlockSubStreamR eader(stream)).

On top of this i have a 4-byte magic ID, so I can do
serialize/deserialize using multiple protocols from a simple interface:

public interface IObjectChannel: IDisposable
{
/// <summary>
/// Send object down the channel
/// </summary>
void SendObject(Obje ct o);
/// <summary>
/// Read object from channel
/// </summary>
/// <exception cref="ObjectCha nnels.Closed">O bjectChannels.C losed
is thrown if the transport is closed
/// before any data is received</exception>
Object ReceiveObject() ;
}

I have a (rather pretty, if I should say it myself) implementation (and
some rather nifty handshaking and stuff) making up a transparent way of
shipping objects from one .NET instance to another, including extensive
unit and integration-tests.

Clients can now do (/actual code from test/)

using ( IObjectChannel c = ksio.ChannelPoo l.Global.Connec t(host,port))
{
c.SendObject(co mmand);
Object reply = c.ReceiveObject ();
}

Which will reuse an existing connection if one is available, and GC
connections that are idle for more than a specific time (default: 1minute).

Servers simply do (/actual code from test - implements an "echo-service"/)

Socket s = ...;
try
{
using ( NetworkStream stream = new NetworkStream(s , true) )
while ( true )
using ( IObjectChannel c =
ObjectChannels. Auto.Global.Cre ate(stream) )
c.SendObject(c. ReceiveObject() );
}
catch ( ObjectChannels. MagicIdObjectCh annel.Closed)
{
// That's the expected way to close
}
catch ( Exception e )
{
Console.WriteLi ne("UNEXPECTED END\n{0}", e);
}

The entire stuff (including a version that does gzip compression on the
data, thanks to ICSharpCode.Sha rpZipLib) is about 200kb worth of code,
..proj- and .sln-files, which I would be happy to publish if someone
wants to check it out.

--
Helge
Nov 16 '05 #3
Sahil Malik

Len comes form the socket when I recieved the packet... below is the code
that calls the code that you saw before. I have another system where I send
compressed data that is larger then the buffer size so I send the size as a
header then then wait for all the data to show up. This system was intented
to more or less just monitor the stream and act based on the data so I was
trying to keep the overhead down. Guess I have no choice but to do it the
long way around.

Thanks for the feedback.

/// Display data calls a delegate which inturn is sent to an event which
handles the data.
private void AcceptData(IAsy ncResult result)
{
try
{
StateObject so = (StateObject)re sult.AsyncState ;
if(so.workSocke t == null || !so.workSocket. Connected)
return;

int bytes = so.workSocket.E ndReceive(resul t);

if(bytes > 0)
{
this.displayDat a(so.buffer, bytes);
}
else
{
this.stop = true;
}
recDone.Set();
}
catch(Exception ex)
{ System.Diagnost ics.Debug.Write Line(ex.Message ); }
}
Regards,
John
Nov 16 '05 #4
Helge Jensen

Well I am not trying to send the data down the same stream. I am just
sending it to a TCP socket which is connected. The problem seems to be that
if the receiving function does not take the data from the stream fast
enought I end up with more then one data group in a packet. Now the problem
is taking the data apart. I have another program that uses header when
sending the data I was just trying to avoid in here.

Thanks for the detailed answer!

Regards,
John
Nov 16 '05 #5
John J. Hughes II wrote:
Helge Jensen

Well I am not trying to send the data down the same stream. I am just
sending it to a TCP socket which is connected.
Arent you serializing objects and sending multiple objects through the
same connection and deserializing them when they get to their endpoint?
That's what the code reads like to me, otherwise you can simply pass a
new NetworkStream(s ocket) to Deserialize().

You do NOT want to put the data in a memory-stream, *trust* me. It's
because of the .NET garbage-collector: If the MemoryStream contains less
than 85kb data it will be moved for (probably) every garbage-collection,
which means a copy of a large chunk. If the MemoryStream contains more
than 85kb it will be allocates on the large object heap, and .NET is
very reluctant to free that memory.

Try writing a test-program that sends a few hundred 1Mb objects throgh
and watch your machine crumble :)

Kamstrup (my workplace) used to serialize/deserialize to memory when I
got there, sending roughly 1Mb worth of serialized objects. But that
would make win32 come to a halt, .NET expending >400Mb of memory even
though only 1Mb was sent at a time.

Now, with my new solution, .NET stays below 5Mb mem-usage.
I have also noticed that the number of bytes recieved is always bigger > then the number of bytes deserizlized, any clue why?

As I said, the BinarySerialize r Deserialize() doesn't read all the data
that Serialize() writes, AND it Close()'es the stream afterwards.
Now the problem
is taking the data apart. I have another program that uses header when
sending the data I was just trying to avoid in here.
If you *do* write to MemoryStream's, then you can easily attach
data-length-headers to the data sent, and workaround your problem, as I
suspect you are saying here?

My method is just a streaming way of attaching the lengths, instead of
using a MemoryStream, and then some added bells&whistles from my
previous experiences with protocols :)

There is *no* way around knowing the lengths generated by Serialize if
you wish to read multiple objects from the same connection. I have found
no simple way to predict how many bytes Deserialize doesn't read.
Thanks for the detailed answer!


No problem, I wrestled this beast for about 25hrs of development time,
don't wan't others to go through the same experience.

--
Helge
Nov 16 '05 #6
Code now available as http://slog.dk/~jensen/download/ksio.2705.zip,
straight out of Kamstrup's Subversion-repository.

You are free to do as you please with the code, and welcome to patch it,
and even more welcome to contribute a patch back :)

To make it compile, remove the prebuild-steps (they insert
subversion-specific information not available in the .zip file) and
remove the svn.cs files from the projects (they are generated in the
prebuild steps).

--
Helge
Nov 16 '05 #7
John,

My gut feeling is that you shouldn't be doing BinaryFormatter 's work, i.e.
you shouldn't have to figure out Length to do a deserialize reliably.

Also, unless you splice out individual streams per object, your multi object
stream cannot be reliable. You will be much better off wrapping that into
another object instead that acts as a collection of these various objects,
i.e. BinaryFormatter must have something atomic to work upon.

- Sahil Malik
http://dotnetjunkies.com/weblog/sahilmalik


"John J. Hughes II" <no@invalid.com > wrote in message
news:uE******** ******@TK2MSFTN GP12.phx.gbl...
Sahil Malik

Len comes form the socket when I recieved the packet... below is the code
that calls the code that you saw before. I have another system where I
send compressed data that is larger then the buffer size so I send the
size as a header then then wait for all the data to show up. This system
was intented to more or less just monitor the stream and act based on the
data so I was trying to keep the overhead down. Guess I have no choice
but to do it the long way around.

Thanks for the feedback.

/// Display data calls a delegate which inturn is sent to an event which
handles the data.
private void AcceptData(IAsy ncResult result)
{
try
{
StateObject so = (StateObject)re sult.AsyncState ;
if(so.workSocke t == null || !so.workSocket. Connected)
return;

int bytes = so.workSocket.E ndReceive(resul t);

if(bytes > 0)
{
this.displayDat a(so.buffer, bytes);
}
else
{
this.stop = true;
}
recDone.Set();
}
catch(Exception ex)
{ System.Diagnost ics.Debug.Write Line(ex.Message ); }
}
Regards,
John

Nov 16 '05 #8
Helge,

Awesome inputs !!!

I just recommended something similar to what you just said here, and I
completely concur with your views.

- Sahil Malik
http://dotnetjunkies.com/weblog/sahilmalik
"Helge Jensen" <he**********@s log.dk> wrote in message
news:%2******** ********@tk2msf tngp13.phx.gbl. ..
John J. Hughes II wrote:
Helge Jensen

Well I am not trying to send the data down the same stream. I am just
sending it to a TCP socket which is connected.


Arent you serializing objects and sending multiple objects through the
same connection and deserializing them when they get to their endpoint?
That's what the code reads like to me, otherwise you can simply pass a new
NetworkStream(s ocket) to Deserialize().

You do NOT want to put the data in a memory-stream, *trust* me. It's
because of the .NET garbage-collector: If the MemoryStream contains less
than 85kb data it will be moved for (probably) every garbage-collection,
which means a copy of a large chunk. If the MemoryStream contains more
than 85kb it will be allocates on the large object heap, and .NET is very
reluctant to free that memory.

Try writing a test-program that sends a few hundred 1Mb objects throgh and
watch your machine crumble :)

Kamstrup (my workplace) used to serialize/deserialize to memory when I got
there, sending roughly 1Mb worth of serialized objects. But that would
make win32 come to a halt, .NET expending >400Mb of memory even though
only 1Mb was sent at a time.

Now, with my new solution, .NET stays below 5Mb mem-usage.
I have also noticed that the number of bytes recieved is always

bigger > then the number of bytes deserizlized, any clue why?

As I said, the BinarySerialize r Deserialize() doesn't read all the data
that Serialize() writes, AND it Close()'es the stream afterwards.
Now the problem
is taking the data apart. I have another program that uses header when
sending the data I was just trying to avoid in here.


If you *do* write to MemoryStream's, then you can easily attach
data-length-headers to the data sent, and workaround your problem, as I
suspect you are saying here?

My method is just a streaming way of attaching the lengths, instead of
using a MemoryStream, and then some added bells&whistles from my previous
experiences with protocols :)

There is *no* way around knowing the lengths generated by Serialize if you
wish to read multiple objects from the same connection. I have found no
simple way to predict how many bytes Deserialize doesn't read.
Thanks for the detailed answer!


No problem, I wrestled this beast for about 25hrs of development time,
don't wan't others to go through the same experience.

--
Helge

Nov 16 '05 #9
> You do NOT want to put the data in a memory-stream, *trust* me. It's
because of the .NET garbage-collector: If the MemoryStream contains less
than 85kb data it will be moved for (probably) every garbage-collection,
which means a copy of a large chunk. If the MemoryStream contains more
than 85kb it will be allocates on the large object heap, and .NET is very
reluctant to free that memory.

<-- I was trying to validate that paragraph. Look at the code below.

static void Main(string[] args)
{
int i;
byte[] dummydata = System.Text.Enc oding.UTF8.GetB ytes("This is some
dummydata, who cares what's in it as long as it is some decent length. I
think we've reached a decent length now.") ;
for (i = 0; i <= 200000; i++)
{
Console.WriteLi ne("Iteration : " + i.ToString());
MemoryStream ms = new MemoryStream();
ms.Write(dummyd ata, 0, dummydata.Lengt h);
}
Console.Read();
}

My mem usage didn't go crazy, and really why should it .. MemoryStream is a
reference type.

What am I missing? :)

- Sahil Malik
http://dotnetjunkies.com/weblog/sahilmalik

"Helge Jensen" <he**********@s log.dk> wrote in message
news:%2******** ********@tk2msf tngp13.phx.gbl. .. John J. Hughes II wrote:
Helge Jensen

Well I am not trying to send the data down the same stream. I am just
sending it to a TCP socket which is connected.


Arent you serializing objects and sending multiple objects through the
same connection and deserializing them when they get to their endpoint?
That's what the code reads like to me, otherwise you can simply pass a new
NetworkStream(s ocket) to Deserialize().

You do NOT want to put the data in a memory-stream, *trust* me. It's
because of the .NET garbage-collector: If the MemoryStream contains less
than 85kb data it will be moved for (probably) every garbage-collection,
which means a copy of a large chunk. If the MemoryStream contains more
than 85kb it will be allocates on the large object heap, and .NET is very
reluctant to free that memory.

Try writing a test-program that sends a few hundred 1Mb objects throgh and
watch your machine crumble :)

Kamstrup (my workplace) used to serialize/deserialize to memory when I got
there, sending roughly 1Mb worth of serialized objects. But that would
make win32 come to a halt, .NET expending >400Mb of memory even though
only 1Mb was sent at a time.

Now, with my new solution, .NET stays below 5Mb mem-usage.
I have also noticed that the number of bytes recieved is always

bigger > then the number of bytes deserizlized, any clue why?

As I said, the BinarySerialize r Deserialize() doesn't read all the data
that Serialize() writes, AND it Close()'es the stream afterwards.
Now the problem
is taking the data apart. I have another program that uses header when
sending the data I was just trying to avoid in here.


If you *do* write to MemoryStream's, then you can easily attach
data-length-headers to the data sent, and workaround your problem, as I
suspect you are saying here?

My method is just a streaming way of attaching the lengths, instead of
using a MemoryStream, and then some added bells&whistles from my previous
experiences with protocols :)

There is *no* way around knowing the lengths generated by Serialize if you
wish to read multiple objects from the same connection. I have found no
simple way to predict how many bytes Deserialize doesn't read.
Thanks for the detailed answer!


No problem, I wrestled this beast for about 25hrs of development time,
don't wan't others to go through the same experience.

--
Helge

Nov 16 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
1808
by: Willoughby Bridge | last post by:
Hi - Having trouble getting a multipart series of forms to move to the next form. The problem line is: <form method="post" enctype="multipart/form-data" action="Data_Form1.php"> If the "action" parameter is set to the current form (Data_Form1.php) then the data posts to the table correctly, but it does not move to the next form If the "action" parameter is set to the next form in the series then by clicking "submit" it moves to the...
11
2024
by: KarimL | last post by:
Thanks for your advices... but i need to get the Image height because i dynamically resize the height of my webcontrol based on the image height. More i just have the url (relative parth) to the the image but in design time mode all variables concerning Server or Context ar not set ! ...so I can't use MapPath function to obtain the physical parth of the picture ... So my second question is how to retrieve the physical root path of the...
2
1863
by: lanmou | last post by:
hi, i am creating a form in my application which dynamically creates controls by getting information from a table in ms access database .now i would like it to get the text by using another table . my code: Private Sub frmDataEntry_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim cn As New OleDbConnection("Provider=Microsoft.Jet.OleDb.4.0;Data Source=" & Application.StartupPath & "\customer.mdb") ...
6
2158
by: DBC User | last post by:
I have couple of object I serialise and store them in file between session. If you open the files you could see the string values. I want a way to encrypt the data so that if anyone opens the file they shouldn't be able to read it. Just to increase the security of the system. How can I do this? Thanks.
2
2060
by: jodleren | last post by:
Hi! I am making an option, which opens a small window with a picture in it and data about it. I just want a JS script, which will get the picture size, and then set the window accordingly? BR Sonnich
1
3029
davydany
by: davydany | last post by:
Hey guys...a n00b Here for this site. I'm making a sequence class for my C++ class. And The thing is in the array that I have, lets say i put in {13,17,38,18}, when i see the current values for the array data from 0 to3, I get this {13, JUNK VALUE, 17,38, 18} and JUNK VALUE is like 1.8e831 or something like that. This happens when I use the attach() function and use the current() function to display the values at data I really want to...
2
3583
by: rustyc | last post by:
Well, here's my first post in this forum (other than saying 'HI' over in the hi forum ;-) As I said over there: ... for a little side project at home, I'm writing a ham radio web site in uby/Rails. I started it in Perl and gave up on Perl as I went from the 'display the database information on the web page' to the 're-display the information from the database and allow the user to update the database using the web page' stage and realized...
4
6415
by: rakesh.usenet | last post by:
For a particular application of mine - I need a simulation of byte array output stream. * write data onto a stream * getback the contiguous content as an array later for network transport. My code looks as follows. #include <iostream>
7
4446
vikas251074
by: vikas251074 | last post by:
I am getting error above in following code since few days giving tension day and night. How can I solve this? I am facing since Oct.25. in line no. 362 After doing a lot of homework, I am surrendered to you. <%@ Language=VBScript%> <%Option Explicit%>
0
9655
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9498
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10172
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9964
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8993
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7517
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6749
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
1
4069
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3670
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.