Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sending objects with UdpClient C#

Tags:

c#

udpclient

I'm currently testing in visual studio 2010. I made a client and server which both will connect through UdpClient.

I want to send an object from the client to the server. I have two methods to convert the object to bytes and to convert it to an object. Now, when I test my application I can't convert it back to an object once received on the server

My server sees that the object is received and tries to convert it from bytes to the object but this gives an error.

System.Runtime.Serialization.SerializationException was unhandled   Message=Unable to find assembly

This seems okay because both applications are in a different namespace...

These are my methods to convert; Both the same on client and server

public byte[] ToBytes() {
        using (MemoryStream stream = new MemoryStream()) {
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(stream, this);

            stream.Position = 0;

            byte[] byteRij = new byte[1024];

            stream.Read(byteRij, 0, (int)stream.Length);

            return byteRij;
        }
    }

    public static Datagram ToDatagram(byte[] rij) {
        using (MemoryStream stream = new MemoryStream()) {
            stream.Write(rij, 0, rij.Length);

            stream.Position = 0;

            BinaryFormatter formatter = new BinaryFormatter();
            return (Datagram)formatter.Deserialize(stream);
        }
    }

How can I resolve this? Thanks in advance

like image 673
kendepelchin Avatar asked Jun 12 '11 10:06

kendepelchin


2 Answers

You need to put all classes that are serialized in a class library project. Use that library in both the server and the client.

Also note that UDP is not reliable. There is no guarantee that your messages arrive at all.

like image 137
jgauffin Avatar answered Sep 21 '22 10:09

jgauffin


BinaryFormatter is deeply tied to the type metadata. It is not a good choice here, since you have different types. Actually IMO it isn't a good choice anyway :) It is not very version tolerant, and is not portable.

I will openly recommend protobuf-net here (disclosure: I wrote it). It is free OSS, but uses google's protobuf format to fix all the BF problems. It is trivial to setup and use, is faster, and has smaller output than BinaryFormatter. Since it is contract-based you can have different types at each end, as log as they agree on the contract (matching field-numbers etc).

For example:

[ProtoContract]
public class Foo {
    [ProtoMember(1)]
    public string X {get;set;}
    [ProtoMember(2)]
    public int Y {get;set;}
}

And then just use ProtoBuf.Serializer.Serialize(stream, object) to write the data.

You can also work without attribute if you need, it takes a little more setup, but not much.

like image 29
Marc Gravell Avatar answered Sep 21 '22 10:09

Marc Gravell