Simple object remoting using the XmlSerializer

Today, I'm going to talk about how you can use the XmlSerializer, TcpClient and TcpListener classes to create a simple remoting layer to send your custom objects from one device to another.  This post requires the .NET Compact Framework version 2 (beta 1) or the .NET Framework for desktop PCs.

Since NetCF doesn't support the TCP Remoting classes, you will need to setup the network connection yourself.  The serializer handles all of the data transfer.  You can use this technique to send data between any combination of systems which support the XmlSerializer and network connectivity.

As you can see from the code below, there isn't too much to making a simple connection, though a real application will need to be more robust and will typically need to handle bi-directional data flow.

Let's take a look at simple client and server code that remotes a custom object between devices.

Object
The only requirements on the object is that it is serializable.  This means that it contains a nullary constructor and all of the public fields are either read/write or are a collection (supporting the Add method).  The example we will be using is a very simple object containing a name, a team name and a player's jersey number.
public class Player{    public String Name;    pulbic String Team;    public Int32 Number;}

Client
The client application instantiates the Player object and populates it's data fields.
Player p = new Player();p.Name = "David";p.Team = "NetCF";p.Number = 43;

Next, it creates an XmlSerializer object, informing the serializer of the type of data which will be sent.
XmlSerializer xs = new XmlSerializer(typeof(Player));

Once we have our serializer, we create a TcpClient object, get connected to the remote server and acquire the stream to be used to communicate with the server.
TcpClient client = new TcpClient();client.Connect(serverAddress, serverPort);Stream stream = client.GetStream();   
Now, we can serialize our Player object.  Since the stream we provide the serializer is a network stream, the data is sent to the server when the serializer writes the XML.
xs.Serialize(stream, p);

The rest of our client is housekeeping.  We need to be sure to close our stream and client objects.
stream.Close();client.Close();

Server
Now let's take a look at the server code.
Player p;

As with the client, we need to create an XmlSerializer object, informing the serializer of the type of data which will be received.
XmlSerializer xs = new XmlSerializer(typeof(Player));

Next, a listener needs to be created and started.
TcpListener listener = new TcpListener(port);listener.Start();

The listener accepts the incoming connection.
TcpClient client = listener.AcceptTcpClient();

And we can get the data stream from the client which was created by the call to AcceptTcpClient.
Stream stream = client.GetStream();
Now we can deserialize the Player object sent by the remote client.  Like the client, the stream used for deserialization is a network stream.  This causes the data to be received when the serializer reads the XML.
p = (Player)xs.Deserialize(stream);

Again, we need to perform some housekeeping.  We need to be sure to close our stream, client and listener objects.
stream.Close();client.Close();listener.Close();

And we can display the received object.
MessageBox.Show(String.Format("Name: {0}\r\nTeam: {1}\r\nNumber: {2}",               p.Name, p.Team, p.Number));

As mentioned earlier, the above is a very simple example of how to remote a data object using the XmlSerializer.  The networking code for real world applications will likely be significantly more involved and handle being sent and received by both devices.

Enjoy!
-- DK

[Edited to fix formatting]
[Edited to fix typo]

Disclaimers:
This posting is provided "AS IS" with no warranties, and confers no rights.
Some of the information contained within this post may be in relation to beta software. Any and all details are subject to change.