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?
The problem was that i was using
StreamWriter.WriteLine
andStreamReader.ReadLine()
which did not write/read the hole xml file. I usedStreamReader.Read()
in a loop until the symbol that i have set as mark for the "end-of-file
" was met.