.NET Framework Developer Center > .NET Development Forums > .NET Framework Networking and Communication > How to send an Object through network using TCP Sockets?
Ask a questionAsk a question
 

AnswerHow to send an Object through network using TCP Sockets?

  • Sunday, November 01, 2009 2:31 PMprogramatic Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hello there.

    I'm implementing a client/server network program where i require to send objects through TCP sockets. All examples i found on web so far only shows you how to send a simple string message through TCP.


    thanks in advance
    • Moved byHarry ZhuMSFTWednesday, November 04, 2009 3:57 AM (From:Visual C# General)
    •  

Answers

All Replies

  • Sunday, November 01, 2009 3:17 PMMario Cossi Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    You cannot send arbitrary objects directly: TCP only supports sending and receiving sequences of bytes.

    So, you must define a protocol that defines:
    1) how data are serialized / deserialized
    2) how each object is separated from the next.

    Sending strings is just the simplest application of the above: you just define the encoding being used (e.g. ASCII) and how each string is separated from the next (e.g. a "\r\n" sequence).

    For instance, if all the objects you send back and forth are of the same type (or if the type can be unambiguously inferred by the data exchange), you could proceed as follows:

    1) Serialize your object to a byte array using an XmlSerializer.
    2) Send the length of the byte array (this will be a 4 byte array you can get using BitConverter.GetBytes).
    3) Send the byte array.

    The receiver must:

    1) Read 4 bytes from the stream and convert it to a length.
    2) Read that many bytes from the stream and put them in a byte array
    3) Deserialize the byte array using an XmlSerializer.

    HTH
    --mc

  • Sunday, November 01, 2009 3:39 PMTamer OzMVPUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    Here is a object that I serialized and send from tcp/ip

    Hope it helps.

        public class Message
        {
            public Message()
            {
    
            }
            private string _Text;
            public string Text
            {
                get { return _Text; }
                set { _Text = value; }
            }
    
            private Client _Sender = new Client(Environment.MachineName,System.Net.Dns.GetHostAddresses(Environment.MachineName)[0].ToString());
            public Client Sender
            {
                get { return _Sender; }
                set { _Sender = value; }
            }
    
            private Client _Reciever;
            public Client Reciever
            {
                get { return _Reciever; }
                set { _Reciever = value; }
            }
    
            private MessengerBase.MessageType _Type;
            public MessengerBase.MessageType Type
            {
                get { return _Type; }
                set { _Type = value; }
            }
    
            public string Serialize()
            {
                StreamWriter stWriter = null;
                XmlSerializer xmlSerializer;
                string buffer;
                try
                {
                    xmlSerializer = new XmlSerializer(typeof(Message));
                    MemoryStream memStream = new MemoryStream();
                    stWriter = new StreamWriter(memStream);
                    System.Xml.Serialization.XmlSerializerNamespaces xs = new XmlSerializerNamespaces();
                    xs.Add("", "");
                    xmlSerializer.Serialize(stWriter, this, xs);
                    buffer = Encoding.ASCII.GetString(memStream.GetBuffer());
                }
                catch (Exception Ex)
                {
                    throw Ex;
                }
                finally
                {
                    if (stWriter != null)
                        stWriter.Close();
                }
                return buffer;
    
            }
            public void DeSerialize(string xmlString)
            {
                XmlSerializer xmlSerializer;
                MemoryStream memStream = null;
                try
                {
                    xmlSerializer = new XmlSerializer(this.GetType());
                    byte[] bytes = new byte[xmlString.Length];
                    Encoding.ASCII.GetBytes(xmlString, 0, xmlString.Length, bytes, 0);
                    memStream = new MemoryStream(bytes);
                    object objectFromXml = xmlSerializer.Deserialize(memStream);
                    Message a = (Message)objectFromXml;
                    this._Reciever = a.Reciever;
                    this._Sender = a.Sender;
                    this._Text = a.Text;
                    this._Type = a.Type;
    
                }
                catch (Exception Ex)
                {
                    throw Ex;
                }
                finally
                {
                    if (memStream != null)
                        memStream.Close();
                }
            }
    
            public void Send()
            {
                TcpClient tcpClient = new TcpClient(_Reciever.Address.ToString(), int.Parse(System.Configuration.ConfigurationManager.AppSettings["port"]));
                NetworkStream tcpStream = tcpClient.GetStream();
                if (tcpStream.CanWrite)
                {
    
                    string msg = this.Serialize();
                    Byte[] inputToBeSent = System.Text.Encoding.ASCII.GetBytes(msg.ToCharArray());
                    tcpStream.Write(inputToBeSent, 0, inputToBeSent.Length);
                    tcpStream.Flush();
                }
            }
            
        }
    
  • Sunday, November 01, 2009 5:52 PMprogramatic Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    First, thanks for your reply.

    Sorry for not mentioning this earlier, but my application server is implemented by java (a requirement - so can't change) and my client is C#. So how can i send over to the java server?

    Your above solution (must?) require the server to do:

    1) Read 4 bytes from the stream and convert it to a length.
    2) Read that many bytes from the stream and put them in a byte array
    3) Deserialize the byte array using an XmlSerializer.

    In that case how can i get a C# client to interact with Java server?

    Or is this impossible?

    PS. i can make a C# client successfully send a String message across to Java server and retreive it back.
  • Saturday, November 07, 2009 3:54 PMprogramatic Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    This problem is unsolved. For time being, question abandoned. Feel free to suggest solutions over time.
  • Sunday, November 08, 2009 4:58 AMFeroze Daud Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Both the above answers are correct. Basically, you define how you want to convert the object to bytes for sending, and then convert received bytes back into the object for receiving.

    If this was the same platform, you could use a serialization method such as XmlSerialization or BinarySerialization.

    You can get it to work even on heterogenous platforms (.net -> java). Just make sure that your serializer/deserialzer on each side (sending and receiving) can deal with the wire format of the object being sent.

    On the java side  you can use Apache Digester to deserialize/serialize the object. On the .NET side you can use XmlSerializzer.


    feroze
    --
    My blog
    Instruction on how to create a tracelog with your System.Net application
  • Sunday, November 08, 2009 1:47 PM_Nobby_ Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Your solution should be platform independent. Typically, I perform serialisation without any high level parsers which could cause deserialisation/serialisation issues between platforms. You should serialise/deserialise your objects directly as byte arrays. Since you have a requirement of the java-based server and creating .Net framework clients, go with the byte[] serialisation. It's a tiny bit more code but ensures no development issues/complexities for cross-platform communications.
  • Sunday, November 15, 2009 3:51 PMFeroze Daud Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    I wrote an article on how to send an object containing primitive types, between a Java app and a .NET app, and back.

    http://ferozedaud.blogspot.com/2009/11/howto-serialize-data-from-object-from.html Hope this helps.
    feroze
    --
    My blog
    Instruction on how to create a tracelog with your System.Net application
    • Proposed As Answer byFeroze Daud Sunday, November 15, 2009 3:51 PM
    • Marked As Answer byprogramatic Sunday, November 15, 2009 7:52 PM
    •  
  • Sunday, November 15, 2009 7:55 PMprogramatic Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    This looks useful.