Error when transfering XML data through TCP sockets: XmlException: Document element did not appear

122 Views Asked by At

I am trying to create an online Checkers game to start learning about networking. I have a server/client architecture and I am using TCP sockets. I would like to send a custom object through the stream. I use an XML serialization system to do that and everything seems to work until the point the client needs to de-serialize the "serialized" message from the server. When this point is reached, I get this error:

XmlException: Document element did not appear. Line 1, position 1. Mono.Xml2.XmlTextReader.Read () System.Xml.XmlTextReader.Read () System.Xml.XmlReader.MoveToContent () System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadRoot () System.Xml.Serialization.XmlSerializer.Deserialize (System.Xml.Serialization.XmlSerializationReader reader)

This is the function I use for serializing an object:

private string Serialize(List<PieceInfo> pieces)
{

    StreamWriter stWriter = null;
    XmlSerializer xmlSerializer;
    string buffer;
    try
    {
        xmlSerializer = new XmlSerializer(typeof(List<PieceInfo>));
        MemoryStream memStream = new MemoryStream();
        stWriter = new StreamWriter(memStream);
        XmlSerializerNamespaces xs = new XmlSerializerNamespaces();
        xs.Add("", "");
        xmlSerializer.Serialize(stWriter, pieces, xs);
        buffer = Encoding.ASCII.GetString(memStream.GetBuffer());
        return buffer;
    }


    catch (Exception Ex)
    {
        throw Ex;
    }    
}

This is the function I use for de-serialization:

public List<PieceInfo> DeSerialize(string xmlString) 
{
    XmlSerializer xmlSerializer;
    MemoryStream memStream = null;
    try
    {
        xmlSerializer = new XmlSerializer(typeof(List<PieceInfo>));            

        byte[] bytes = new byte[xmlString.Length];
        Encoding.ASCII.GetBytes(xmlString, 0, xmlString.Length, bytes,0);
        memStream = new MemoryStream(bytes);
        memStream.Seek(0, SeekOrigin.Begin);
        object objectFromXml = xmlSerializer.Deserialize(memStream);
        List<PieceInfo> pieces = (List<PieceInfo>)objectFromXml;
        return pieces;
    }
    catch (Exception Ex)
    {
        throw Ex;
    }
} 

Sending message code:

StreamWriter writer = new StreamWriter(tcpClient.GetStream());
writer.WriteLine("GRABB~"+ Serialize(ListPiecesForSerilization));
writer.Flush();

Receiving messages code:

private void OnIncomingData(string data)
{
    string[] lines;
    lines = data.Split('~');
    for (int i = 0; i != lines.Length; i++)
    {
        switch (lines[i])
        {                                          
            case "GRABB": // get board's current condition
                List<PieceInfo> pieces = DeSerialize(lines[i+1]);
                board.SetPiecesPosition(pieces);
                break;
        }
            //Debug.Log(data);
    }
}

PieceInfo class, contains basic info about a piece:

[Serializable]
public class PieceInfo 
{
    public int xPos;
    public int zPos;
    public bool isWhite;
    public bool isKing;

    public void SetPieceInfo(int x, int z, bool c, bool k)
    {
        xPos = x;
        zPos = z;
        isWhite = c;
        isKing = k;
    }
}

The class PieceInfo is marked with the attribute [Serializable] but I have not set any other attributes in it.

I send the xml message as a string using NetworkStream and StreamWriter/StreamReader.

Why do I get the error when I try to deserialize the message?

1

There are 1 best solutions below

0
On

The problem was that i was using StreamWriter.WriteLine and StreamReader.ReadLine() which did not write/read the hole xml file. I used StreamReader.Read() in a loop until the symbol that i have set as mark for the "end-of-file" was met.