Shaitan00 Posted November 12, 2006 Posted November 12, 2006 I have made my own custom class to SERIALIZE and DE-SERIALIZE a custom object (kind of complicated, the object contains a custom array of custom objects, etc... lets just say I pretty much had to add [serializable] at the top of all my objects). Now the Serialization seems to work perfectly fine HOWEVER when I attempt to de-serialize the data on the other side (I send the data from the SERVER to the CLIENT via a TCP-Channel) I keep getting some odd errors regarding "objectID cannot be less than or equal to zero" Anyways, this is the class I use to perform my Serialization public class Serialization { static private BinaryFormatter bf = new BinaryFormatter(); public static byte[] Serialize(object data) { try { MemoryStream ms = new MemoryStream(); bf.Serialize(ms, data); return ms.ToArray(); } catch (Exception ex) { Log.Trace("Serialize:: General Exception: " + ex); return null; } } public static object Deserialize(byte[] data) { try { MemoryStream ms = new MemoryStream(data); return bf.Deserialize(ms); } catch (Exception ex) { Log.Trace("Deserialize:: General Exception: " + ex); return null; } } } } And this is the exact EXCEPTION error message I get (when caught) in the "Deserialize" function above... [Exception] Deserialize:: General Exception: System.ArgumentOutOfRangeException: objectID cannot be less than or equal to zero. Parameter name: objectID at System.Runtime.Serialization.ObjectManager.GetObject(Int64 objectID) at System.Runtime.Serialization.Formatters.Binary.ObjectReader.ParseArrayMember(ParseRecord pr) at System.Runtime.Serialization.Formatters.Binary.ObjectReader.ParseMember(ParseRecord pr) at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Parse(ParseRecord pr) at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadMemberReference() at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run() at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage) at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage) at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream) at Application.Serialization.Deserialize(Byte[] data) [/Exception] I am totally lost and I can't seem to find any information regarding this type of error... I must admit this is my first attempt at Serialization/DeSerialization of custom objects but I would have assumed it would work fine... Any ideas, hints, and help would be greatly appreciated, thanks Quote
MrPaul Posted November 12, 2006 Posted November 12, 2006 Serialization issue or socket issue? My first question would be - does the data deserialize correctly within the application that serialized it? Assuming that is the case, do you have any safeguards to check that the size of the data received is the same as the size of the data that was transmitted? The data may be fragmented in transit and arrive at the recipient in chunks, so the recipient must reassemble the data and not attempt deserialization until it has all been received. Good luck :cool: Quote Never trouble another for what you can do for yourself.
Shaitan00 Posted November 12, 2006 Author Posted November 12, 2006 1- Looks like I am able to De-Serialize in the application itself (doesn't generate any errors when I .Serialize(Object) and right after .Deserialize(byte).. I would assume that means it works... 2- As for the sending of the data... I do it the following way: -= SENDER =- // Send Data Length int nLen = byteData.Length; byte[] byteLen = BitConverter.GetBytes(nLen); nsClient.Write(byteLen, 0, 4); nsClient.Flush(); // Send Data to Client nsClient.Write(byteData, 0, byteData.Length); nsClient.Flush(); Where NSCLIENT is a NETWORKSTREAM in conjunction with a TCP channel and BYTEDATA is the actual serialized data of my object. -= RECIEVER =- // Get Size byte[] byteLen = new byte[4]; int nRecvLen = nsServer.Read(byteLen, 0, 4); int nLen = BitConverter.ToInt32(byteLen, 0); // Get Data byte[] byteData = new byte[nLen]; int nRecvData = nsServer.Read(byteData, 0, nLen); // Use byteData to Deserialize into my custom object Where NSSERVER is a NETWORKSTEAM in conjunction with a TCP channel... I tried logging the sizes being sent and recieved [nLen] and they are the exact same thing .... Shouldn't this ensure I recieved it all in one shot? Am I going about this the wrong way? Thanks, Quote
MrPaul Posted November 12, 2006 Posted November 12, 2006 Count the actual number of bytes! I tried logging the sizes being sent and recieved [nLen] and they are the exact same thing .... nLen appears to be your own variable, and is not necessarily equivalent to the actual number of bytes received. You need to keep reading until the actual number of bytes received equals nLen. Note that if this is in a callback function (eg asycnhronous sockets) then you will have to code in some logic to determine whether the incoming data is the beginning of a new set of data, or the next chunk of the last set of data. For example: //The variables nLenTotal, nLenCurrent and byteData MUST be persisted between events, //i.e. they must be class-level variables if (nLenTotal == 0) { //Must be the beginning of some new data //Get size byte[] byteLen = new byte[4]; nRecvLen = nsServer.Read(byteLen, 0, 4); nLenTotal = BitConverter.ToInt32(byteLen, 0); //Initialize byte array byteData = new byte[nLenTotal]; nLenCurrent = 0; } //Read some data nRecvData = nsServer.Read(byteData, nLenCurrent, nLenTotal - nLenCurrent); nLenCurrent += nRecvData; if (nLenCurrent == nLenTotal) { //Received all data, now can deserialize } Quote Never trouble another for what you can do for yourself.
Shaitan00 Posted November 13, 2006 Author Posted November 13, 2006 (edited) Works perfectly - thanks ... I had made a bad assumption that the entire data had been transfered in one single burst... Thanks a lot !!! Edited November 13, 2006 by Shaitan00 Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.