Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / March 2008

Tip: Looking for answers? Try searching our database.

XmlSerializer over NetworkStream

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Newbro - 04 Mar 2008 07:38 GMT
I'm developing a server client programs which handle communications between
PC and PDA devices. XmlSerializer is used to serialize Packet object and
send/receive over networkstream.

The program works just fine initially, but choke when there's a constant
stream of data coming, which cause an XmlException to be thrown with error
"There's an error in XML document (....". For example if I were to send a
chat message Packet every other 2 seconds the program will remains ok, but
will throw an XmlException error almost instantly if I were to repeatly
sending a chat message Packet.

Basically both the server and client uses the same two functions SendPacket
and ReceivePacket to send an packet object to the other party, and a thread
calling ReceivePacket every other second.

Anyone care to enlight me on this very matter would be great. Thanks.

public void SendPacket(Packet data)
       {
           if (data == null) return;
           try
           {
               String xmlString = Helper.SerializePacket(data);
               Byte[] buffer = Helper.StringToUTF8ByteArray(xmlString);
               networkStream.Write(buffer, 0, buffer.Length);
               networkStream.Flush();            

           }
           catch (Exception e)
           {
               throw e;
           }
       }

       public Packet ReceivePacket()
       {
           try
           {
               Byte[] buffer = new Byte[Packet._PACKET_BYTE];
               int bufferSize = networkStream.Read(buffer, 0, buffer.Length);
               String xmlString = Helper.UTF8ByteArrayToString(buffer);
               return (Helper.DeserializePacket(xmlString));              
                           
           }
           catch (Exception e)
           {
               throw e;
           }
       }

/// <summary>
       /// Convert a Byte array to UTF-8 encoded string
       /// </summary>
       /// <param name="characters">Byte array to be converted</param>
       /// <returns>String representation of given byte array</returns>
       public static String UTF8ByteArrayToString(Byte[] characters)
       {

           UTF8Encoding encoding = new UTF8Encoding();
           String constructedString = encoding.GetString(characters, 0,
characters.Length);
           return (constructedString);
       }

       /// <summary>
       /// Convert a UTF-8 encoded string to Byte array
       /// </summary>
       /// <param name="pXmlString">String to be converted</param>
       /// <returns>Byte array representation of given string</returns>
       public static Byte[] StringToUTF8ByteArray(String pXmlString)
       {
           UTF8Encoding encoding = new UTF8Encoding();
           Byte[] byteArray = encoding.GetBytes(pXmlString);
           return byteArray;
       }

       /// <summary>
       /// Serialize a Packet object into a UTF-8 encoded string
       /// </summary>
       /// <param name="packetObj">Packet to be serialized</param>
       /// <returns>Serialized string of given object</returns>
       public static String SerializePacket(Packet packetObj)
       {
           try
           {
               String XmlizedString = null;
               MemoryStream memoryStream = new MemoryStream();
               XmlSerializer xs = new XmlSerializer(typeof(Packet));
               XmlTextWriter xmlTextWriter = new
XmlTextWriter(memoryStream, Encoding.UTF8);
               xs.Serialize(xmlTextWriter, packetObj);
               memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
               XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());
               return XmlizedString;
           }
           catch (Exception e)
           {
               throw e;
           }
       }

       /// <summary>
       /// Deserialize a string into Packet object
       /// </summary>
       /// <param name="xmlString">String to be deserialized</param>
       /// <returns>Packet object of the given string</returns>
       public static Packet DeserializePacket(String xmlString)
       {
           try
           {
               XmlSerializer xs = new XmlSerializer(typeof(Packet));
               MemoryStream memoryStream = new
MemoryStream(StringToUTF8ByteArray(xmlString));
               XmlTextWriter xmlTextWriter = new
XmlTextWriter(memoryStream, Encoding.UTF8);
               return (Packet)xs.Deserialize(memoryStream);
           }
           catch (Exception e)
           {
               throw e;
           }
       }
Ollie - 04 Mar 2008 16:58 GMT
Hi,

I believe it would be better to convert your string into a base64 encoded
string than a UTF-8 string. Are you sure that you aren't getting some
character translation when your 'packet' class is passed over the wire?

check out base 64 encoding...

Also you can remove the number of lines from serialisation code -where
'Test' represents your class:

string ser1 = string.Empty;
System.Text.StringBuilder sb = new System.Text.StringBuilder();
using(StringWriter sw = new StringWriter(sb))
{
    XmlSerializer ser = new XmlSerializer(typeof(Test));
    ser.Serialize(sw, test);           

    ser1 = sb.ToString();
}

And for deserialisation you can do the following - where 'Test' represents
your class:

Test test1 = null;
using(StringReader sr = new StringReader(ser1))
{
    XmlSerializer ser = new XmlSerializer(typeof(Test));
    test1 = (Test)ser.Deserialize(sr);           
}

Hope this helps

Ollie

> I'm developing a server client programs which handle communications between
> PC and PDA devices. XmlSerializer is used to serialize Packet object and
[quoted text clipped - 118 lines]
>             }
>         }
Filip Larsen - 04 Mar 2008 22:13 GMT
Newbro skrev:

> I'm developing a server client programs which handle communications between
> PC and PDA devices. XmlSerializer is used to serialize Packet object and
[quoted text clipped - 3 lines]
> stream of data coming, which cause an XmlException to be thrown with error
> "There's an error in XML document (....".

I've only glanced quickly at your code, but it do seem you need to
properly demarcate the packets you send, say, using length delimiting in
your SendPacket method. Using Write to send a "bare" byte buffer will
not in itself isolate one packet from the other in the receiving end,
which may get part of one packet, or a mix of both.

Sender do like:

byte[] data = ...
Stream stream = ...
BinaryWriter out = new BinaryWriter(stream);
out.Write(data.Length);
out.Write(data);
out.Flush();

and receiver do

Stream stream = ...
BinaryReader in = new BinaryReader(stream);
int32 len = in.ReadInt32();
byte[] data = in.ReadBytes(len);

Regards,
Signature

Filip Larsen

Newbro - 05 Mar 2008 01:13 GMT
Yes I think that was the problem, isloating one Packet from another in
receiving.

I end up using a solution simlilar to Filip's, using first 4 bytes to hold
the length of the trailing Packet data bytes size, and seems to be working
fine just now. Thanks all

> Newbro skrev:
>
[quoted text clipped - 29 lines]
>
> Regards,

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.