How to send an object through a socket C#

11,637

Solution 1

You have to "serialize" the objects, and and de-serialize them on the other side. See http://msdn.microsoft.com/en-us/library/system.serializableattribute.aspx for information about that.

You have to be careful though, if something happens to the connection while sending the data, you might have not enough data to completely re-create the objects, and your program may fail in some unexpected place. Only create the objects if you received everything.

Solution 2

You have plenty objects for serializing, such as binary, XML, JSON, but there is also a remoting approach, not to say that you can create web service. In two last cases, 'sending' and object is trivial and it amounts to putting it in a method signature as a parameter.

Solution 3

Why do you want to send data through sockets yourself, while protocols to do this (higher than TCP) already have proven their worth?

You'd have to create a protocol to send and receive the data, and implement this protocol, where you'll spend a lot of time on things that have been done before and have been around for many years. Not to mention the time spent debugging something boring that can be used for the cooler part of programming, putting a language and framework to work for the "boring" part, and link it together to solve the problem you're having.

Things you have to care about are for exapmple separators for different data objects and dropped connections (a kind of Content-Length header in your protocol to tell the receiving side how much data it has to expect).

Why don't you simply use WCF, as a wrapper for SOAP, REST or JSON (if the other side speaks that) or Net.TCP if you are to implement both client and server?

You then simply can call the service method MyObject[] GetObjects(): all the boring stuff will be dealt with by the framework, and you receive your MyObject array as-is on the client side. In the background everything from HTTP headers to serializing to detecting dropped connections and throwing relevant exceptions will be done for you. This saves serious time and trouble.

Or you could use plain HTTP, create a small web application where you can request the data in a serialized format you like and deserialize the data on the client side after receiving it through an HttpClient.

Share:
11,637

Related videos on Youtube

Taufiq Abdur Rahman
Author by

Taufiq Abdur Rahman

Updated on June 04, 2022

Comments

  • Taufiq Abdur Rahman
    Taufiq Abdur Rahman almost 2 years

    I have a list of objects and I want to sent it thought TCP socket connection. One way is to take the object list and get all the values separating them by comas and the receiving data and on the other end and values in a object. Can I send a object list as it can be done in WCF web service. It so can you show me how? Thanks!

    I did already created a WCF Service for this but changed it as it has a few issues that can't be solved. So I am creating this Client server application.

    Also the data that is being send is refreshed every few seconds, and it will be needed by a lot of users. After some research I found out this would be a better option.

    I have this class with which I was sending my messages through

    public void SendMessage(string text)
    {
        Byte[] bytesSent = Encoding.UTF8.GetBytes(text);
        SocketAsyncEventArgs writeEventArgs = new SocketAsyncEventArgs();
        writeEventArgs.SetBuffer(bytesSent, 0, bytesSent.Length);
        socket.SendAsync(writeEventArgs);
    }
    

    But I would out rather serialize the object first and then send it. So I have a stream and need as a byte array.

    This what I have to receive data:

    void ReceiveData()
    {
        try
        {
            int recv;
            string stringData;
            while (true)
            {
                recv = socket.Receive(data);
                stringData = Encoding.ASCII.GetString(data, 0, recv);
                if (stringData == "bye")
                    break;
                ClientDataRecievedEventArgs sd = new ClientDataRecievedEventArgs(stringData);
                DataRecieved(this, sd);
            }
            stringData = "bye";
            byte[] message = Encoding.ASCII.GetBytes(stringData);
            socket.Send(message);
            socket.Close();
            this.Dispose();
            return;
        }
        catch (Exception)
        {
            socket.Close();
            this.Dispose();
        }
    
    }
    

    This is want I am using:

    SoapFormatter formatter = new SoapFormatter();
    
    foreach (Communication.Client Client in server.ClientList)
    {
        foreach (ObjectLibrary.Model.PIP p in Repository.GlobalRepository.PIPInformation)
        {
    
            formatter.Serialize(stream, p);
            Client.SendMessage(stream);
        }
    }
    

    How do I initialize the stream? I need to get the data as Stream to deserialize it to Object.

    And so I have list of Objects Can I serialize a whole list?

    • Pawan Mishra
      Pawan Mishra over 12 years
      Did you try any code from your end? If yes, then you can be specific as what problems you are facing in sending list of objects through tcp socket.
    • ViktorZ
      ViktorZ over 12 years
      Also check out this thread [Send serialised object via socket][1] [1]: stackoverflow.com/q/1536169/164906
    • Merlyn Morgan-Graham
      Merlyn Morgan-Graham over 12 years
      @Taufiq: If you have very strong latency requirements (e.g. you're creating a networked first person shooter, or other real-time physics based game), or are trying to implement a new or existing low-level Internet protocol, only then would I keep going with a socket-based approach. Otherwise I'd look into simpler and higher level technologies like WCF. It is way more flexible (as far as code factoring goes), and will let you avoid thinking about most of the details most of the time.
    • Taufiq Abdur Rahman
      Taufiq Abdur Rahman over 12 years
      Merlyn Morgan-Graham i updated my question hope u can help me!
  • Some programmer dude
    Some programmer dude over 12 years
    Either serialize all objects in the list, and put the serialized data in a big buffer and send the whole buffer at once; Or iterate over lsit list, serializing one object and send it right away. The first alternative is best if you need to send the whole list, the second if it is ok to send a partial list (in case of error.)
  • CodeCaster
    CodeCaster over 12 years
    You have problems with WCF that can't be solved, so you start to create your own layer? You really better spend more time getting WCF to work. Or host the data in IIS and let the clients poll for new data through HTTP. And if you don't see what's wrong with if (stringData == "bye") break; I really can't help you.
  • Taufiq Abdur Rahman
    Taufiq Abdur Rahman over 12 years
    Also the code was taken from a simpler project. Which seems to work fine, and also i am armature in this field, so the code if (stringData == "bye") break; has a problem i dont see it. Would kindly explain thanks.
  • Taufiq Abdur Rahman
    Taufiq Abdur Rahman over 12 years
    The problem with WCF please help me out if u can stackoverflow.com/questions/7899172/…
  • CodeCaster
    CodeCaster over 12 years
    I think you mean amateur. ;-) But it's never guaranteed for a string you send ("Bye") to be received in one piece. It's perfectly possible for your data to be received in multiple packets. It's highly unlikely, but in theory (with a lot of network congestion, full buffers and whatnot) it's possible you receive three packets, "B", "y" and "e". Then your program doesn't work. I'll have a look at your WCF problem.
  • Taufiq Abdur Rahman
    Taufiq Abdur Rahman over 12 years
    Oooh! by the why what would be the right approach to this problem?
  • CodeCaster
    CodeCaster over 12 years
    That's up to you, based on your protocol specification. You could take a look at HTTP, for example. This reads all incoming bytes up till an CrLf (Enter), and then parses the request header as it's being called. Once the headers have been sent, the client sends two CrLf's so the server knows it can start sending data back. This can be demonstrated by telnetting to Google.com on port 80, and typing "GET / HTTP/1.1 (Enter) Host: google.com (Enter)(Enter)". The HTTP server at Google will receive this character by character, and still returns a meaningful response.