Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Sockets/Objects/Serializable

Sockets/Objects/Serializable

Scheduled Pinned Locked Moved C#
10 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Offline
    P Offline
    Paddy
    wrote on last edited by
    #1

    I'm new to C# and was looking for help on sending objects through sockets. I have a program(which I got from this site) that sends bytes through a socket, it's a client/server chat program. I have written a class and made it Serializable and am trying to send instances of my class through the socket but haven't a clue how to actually serialize the object into bytes and send it through the socket. Hope someone can help, Paddy.

    J T 2 Replies Last reply
    0
    • P Paddy

      I'm new to C# and was looking for help on sending objects through sockets. I have a program(which I got from this site) that sends bytes through a socket, it's a client/server chat program. I have written a class and made it Serializable and am trying to send instances of my class through the socket but haven't a clue how to actually serialize the object into bytes and send it through the socket. Hope someone can help, Paddy.

      J Offline
      J Offline
      James T Johnson
      wrote on last edited by
      #2

      public byte[] GetObjectBytes(object o)
      {
      MemoryStream memstream = new MemoryStream();
      IFormatter formatter = new BinaryFormatter();

      formatter.Serialize(memstream, o);

      memstream.Close(); // Prevent further writing

      return memstream.GetBuffer();
      }

      public object GetObjectFromBytes(byte [] bytes)
      {
      MemoryStream memstream = new MemoryStream(bytes);
      IFormatter formatter = new BinaryFormatter();

      object o = formatter.Deserialize(memstream);

      memstream.Close();

      return o;
      }

      I'm not a network guy, but I assume you just call the Write method on the NetworkStream object representing your socket, to send the byte array, then call the Read method on the other side to read back the byte array. GetObjectBytes() will serialize the object and return the byte array which you can pass to Write, GetObjectFromBytes() will deserialize the byte array from the Read method. HTH, James Simplicity Rules!

      1 Reply Last reply
      0
      • P Paddy

        I'm new to C# and was looking for help on sending objects through sockets. I have a program(which I got from this site) that sends bytes through a socket, it's a client/server chat program. I have written a class and made it Serializable and am trying to send instances of my class through the socket but haven't a clue how to actually serialize the object into bytes and send it through the socket. Hope someone can help, Paddy.

        T Offline
        T Offline
        tmagoo
        wrote on last edited by
        #3

        I am having sort of the same problems as you are. Instead I am trying to make class variables equal to the bytes returned from the socket. I sort of understand what James T. Johnson is giving you advise on; but, I don't know how to make a custom object in C#. Since I am using class variables instead of objects, I am leaving you this test code to show you how I convert the byte types to the variables in a class. This example requires the knowledge of byte masking and the use of Reflection. I am hoping to get some feedback plus maybe show you something new dealing with Reflection. using System; using System.Reflection; namespace ConvertTypes { /// /// Summary description for ConvertTypes. /// /// class ConvertClass { public int x; public int y; public bool z; public ConvertClass(int i, int j, bool k) { x = i; y = j; z = k; } // Set the converted value public void SetConvertClass(int i, string sName) { if(sName == "x") x = i; else y = i; } } class clsConvertTypes { /// /// The main entry point for the application. /// [STAThread] static void Main(string[] args) { ConvertClass mCls = new ConvertClass(0,0,true); //Declare 8 Bytes for 2 int's byte [] bTest = new Byte[8]; // get a Type Object representing ConvertClass Type t = typeof(ConvertClass); // get the fields from the Type object (ie int x, int y) FieldInfo [] fi = t.GetFields(); // Start at index 0 which represents the x field int iIndex = 0; //Build the x value as 500000 and the y value as 400000 bTest[0] = 0x00; // 0x0007A120 = 500000 bTest[1] = 0x07; bTest[2] = 0xA1; bTest[3] = 0x20; bTest[4] = 0x00; // 0x00061A80 = 400000 bTest[5] = 0x06; bTest[6] = 0x1A; bTest[7] = 0x80; foreach(FieldInfo FI in fi) { if(FI.FieldType == typeof(int)) { // Declare a temporary integer variable int iTemp; // Mask the byte array into a single integer iTemp = (int)((bTest[iIndex]<<24) | (bTest[iIndex+1] << 16) | (bTest[iIndex+2] << 8) | bTest[iIndex+3]); // increment the index by 4 bytes since it is a int iIndex = iIndex + 4; // Declare an object which will be used to pass // parameters to the SetConvertClass method object[] targs = new Object[2]; targs[0] = iTemp; //First argument targs[1] = FI.Name; //Second argument (x or y) /

        J 1 Reply Last reply
        0
        • T tmagoo

          I am having sort of the same problems as you are. Instead I am trying to make class variables equal to the bytes returned from the socket. I sort of understand what James T. Johnson is giving you advise on; but, I don't know how to make a custom object in C#. Since I am using class variables instead of objects, I am leaving you this test code to show you how I convert the byte types to the variables in a class. This example requires the knowledge of byte masking and the use of Reflection. I am hoping to get some feedback plus maybe show you something new dealing with Reflection. using System; using System.Reflection; namespace ConvertTypes { /// /// Summary description for ConvertTypes. /// /// class ConvertClass { public int x; public int y; public bool z; public ConvertClass(int i, int j, bool k) { x = i; y = j; z = k; } // Set the converted value public void SetConvertClass(int i, string sName) { if(sName == "x") x = i; else y = i; } } class clsConvertTypes { /// /// The main entry point for the application. /// [STAThread] static void Main(string[] args) { ConvertClass mCls = new ConvertClass(0,0,true); //Declare 8 Bytes for 2 int's byte [] bTest = new Byte[8]; // get a Type Object representing ConvertClass Type t = typeof(ConvertClass); // get the fields from the Type object (ie int x, int y) FieldInfo [] fi = t.GetFields(); // Start at index 0 which represents the x field int iIndex = 0; //Build the x value as 500000 and the y value as 400000 bTest[0] = 0x00; // 0x0007A120 = 500000 bTest[1] = 0x07; bTest[2] = 0xA1; bTest[3] = 0x20; bTest[4] = 0x00; // 0x00061A80 = 400000 bTest[5] = 0x06; bTest[6] = 0x1A; bTest[7] = 0x80; foreach(FieldInfo FI in fi) { if(FI.FieldType == typeof(int)) { // Declare a temporary integer variable int iTemp; // Mask the byte array into a single integer iTemp = (int)((bTest[iIndex]<<24) | (bTest[iIndex+1] << 16) | (bTest[iIndex+2] << 8) | bTest[iIndex+3]); // increment the index by 4 bytes since it is a int iIndex = iIndex + 4; // Declare an object which will be used to pass // parameters to the SetConvertClass method object[] targs = new Object[2]; targs[0] = iTemp; //First argument targs[1] = FI.Name; //Second argument (x or y) /

          J Offline
          J Offline
          James T Johnson
          wrote on last edited by
          #4

          That's pretty what the binary serializer does except it has type safety built in. Using the methods I created you would do something like this.

          private byte[] GetMyClassBytes(MyClass mc)
          {
          return GetObjectBytes(mc);
          }

          private MyClass GetMyClassFromBytes(byte[] bytes)
          {
          return (MyClass) GetObjectFromBytes(bytes);
          }

          To go from object to a specifc class you just need to cast or use the as keyword if you don't want to throw an exception if it is the wrong type (return GetObjectFromBytes(bytes) as MyClass returns null if the object isn't of type MyClass). James Simplicity Rules!

          P T 3 Replies Last reply
          0
          • J James T Johnson

            That's pretty what the binary serializer does except it has type safety built in. Using the methods I created you would do something like this.

            private byte[] GetMyClassBytes(MyClass mc)
            {
            return GetObjectBytes(mc);
            }

            private MyClass GetMyClassFromBytes(byte[] bytes)
            {
            return (MyClass) GetObjectFromBytes(bytes);
            }

            To go from object to a specifc class you just need to cast or use the as keyword if you don't want to throw an exception if it is the wrong type (return GetObjectFromBytes(bytes) as MyClass returns null if the object isn't of type MyClass). James Simplicity Rules!

            P Offline
            P Offline
            Paddy
            wrote on last edited by
            #5

            Thanks for the help. I haven't got a chance to try it out yet but that should fix the problem. I'll give it a go later on. I can't get my head around Tom's code though coz I'm only learning C# at the moment. Thanks, Paddy.

            1 Reply Last reply
            0
            • J James T Johnson

              That's pretty what the binary serializer does except it has type safety built in. Using the methods I created you would do something like this.

              private byte[] GetMyClassBytes(MyClass mc)
              {
              return GetObjectBytes(mc);
              }

              private MyClass GetMyClassFromBytes(byte[] bytes)
              {
              return (MyClass) GetObjectFromBytes(bytes);
              }

              To go from object to a specifc class you just need to cast or use the as keyword if you don't want to throw an exception if it is the wrong type (return GetObjectFromBytes(bytes) as MyClass returns null if the object isn't of type MyClass). James Simplicity Rules!

              T Offline
              T Offline
              tmagoo
              wrote on last edited by
              #6

              Paddy thanks for starting this discussion. I knew there was an easier way of doing what we wanted. It just takes time to learn and get help on the in's and out's of the language. Thank you James for your help. You've solved the problem that I am having. Thanks again, Tom McDaniel

              P 1 Reply Last reply
              0
              • T tmagoo

                Paddy thanks for starting this discussion. I knew there was an easier way of doing what we wanted. It just takes time to learn and get help on the in's and out's of the language. Thank you James for your help. You've solved the problem that I am having. Thanks again, Tom McDaniel

                P Offline
                P Offline
                Paddy
                wrote on last edited by
                #7

                No problem, James has solved the problem for me too. I know what you mean about the in's and out's, I find it's always something small that gets me stuck for days but it's great when someone can give you the solution straight away off the top of their head! Thanks James, Paddy.

                1 Reply Last reply
                0
                • J James T Johnson

                  That's pretty what the binary serializer does except it has type safety built in. Using the methods I created you would do something like this.

                  private byte[] GetMyClassBytes(MyClass mc)
                  {
                  return GetObjectBytes(mc);
                  }

                  private MyClass GetMyClassFromBytes(byte[] bytes)
                  {
                  return (MyClass) GetObjectFromBytes(bytes);
                  }

                  To go from object to a specifc class you just need to cast or use the as keyword if you don't want to throw an exception if it is the wrong type (return GetObjectFromBytes(bytes) as MyClass returns null if the object isn't of type MyClass). James Simplicity Rules!

                  T Offline
                  T Offline
                  tmagoo
                  wrote on last edited by
                  #8

                  The GetObjectBytes does not return the bytes as expected. Consider the following code. using System; using System.IO; using System.Threading; using System.Text; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; namespace CBinFormatter { /// /// Summary description for Class1. /// class CBinFormatter { [Serializable()] public struct sValues { public int iFirst; public int iSecond; public int iThird; } /// /// The main entry point for the application. /// [STAThread] static void Main(string[] args) { // // TODO: Add code to start application here // sValues sVal = new sValues(); sVal.iFirst = 100; sVal.iSecond = 300; sVal.iThird = 400; byte [] btVal = GetObjectBytes(sVal); Console.WriteLine("The size of the btVal is " + btVal.Length); } static byte[] GetObjectBytes(object o) { MemoryStream memstream = new MemoryStream(); IFormatter formatter = new BinaryFormatter(); formatter.Serialize(memstream, o); memstream.Close(); // Prevent further writing return memstream.GetBuffer(); } static object GetObjectFromBytes(byte [] bytes) { MemoryStream memstream = new MemoryStream(bytes); IFormatter formatter = new BinaryFormatter(); object o = formatter.Deserialize(memstream); memstream.Close(); return o; } } } The Binary Serializer will return a size which is greater than the three int variables from the structure. Plus, when looking at the byte values within the debugger, I can't find the 100, 300, 400. I would of expected that the bytes returned would of been the size of 12 bytes " 3 int values - 4 bytes each". Do you know what I am missing here? Tom McDaniel

                  J 1 Reply Last reply
                  0
                  • T tmagoo

                    The GetObjectBytes does not return the bytes as expected. Consider the following code. using System; using System.IO; using System.Threading; using System.Text; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; namespace CBinFormatter { /// /// Summary description for Class1. /// class CBinFormatter { [Serializable()] public struct sValues { public int iFirst; public int iSecond; public int iThird; } /// /// The main entry point for the application. /// [STAThread] static void Main(string[] args) { // // TODO: Add code to start application here // sValues sVal = new sValues(); sVal.iFirst = 100; sVal.iSecond = 300; sVal.iThird = 400; byte [] btVal = GetObjectBytes(sVal); Console.WriteLine("The size of the btVal is " + btVal.Length); } static byte[] GetObjectBytes(object o) { MemoryStream memstream = new MemoryStream(); IFormatter formatter = new BinaryFormatter(); formatter.Serialize(memstream, o); memstream.Close(); // Prevent further writing return memstream.GetBuffer(); } static object GetObjectFromBytes(byte [] bytes) { MemoryStream memstream = new MemoryStream(bytes); IFormatter formatter = new BinaryFormatter(); object o = formatter.Deserialize(memstream); memstream.Close(); return o; } } } The Binary Serializer will return a size which is greater than the three int variables from the structure. Plus, when looking at the byte values within the debugger, I can't find the 100, 300, 400. I would of expected that the bytes returned would of been the size of 12 bytes " 3 int values - 4 bytes each". Do you know what I am missing here? Tom McDaniel

                    J Offline
                    J Offline
                    James T Johnson
                    wrote on last edited by
                    #9

                    The binary serializer includes information so that it can deserialize the data correctly. It includes type information (so that it can instantiate the object then load the data into it). Eric Gunnerson pointed out a way to convert from a byte array to the object which is extremely easy; I haven't figured out how to get the byte array as easily though. Here is a test program which shows how it works; compile with the /unsafe compiler switch.

                    using System;
                    using System.Runtime.InteropServices;

                    namespace Test
                    {
                    public struct Data
                    {
                    public int i;
                    public int j;
                    public int k;
                    }

                    public class Driver
                    {
                    public static void Main(string [] args)
                    {
                    byte [] bytes;
                    Data data;
                    Data foo;

                      data.i = 1;
                      data.j = 2;
                      data.k = 3;
                    
                      bytes = ToByteArray(data);
                    
                      foo = FromByteArrayToData(bytes);
                    
                      System.Console.WriteLine("{0}, {1}, {2}", foo.i, foo.j, foo.k);
                    }
                    
                    private static byte\[\] ToByteArray(object data)
                    {
                      // Get size of the object
                      int sizeofData = Marshal.SizeOf(data);
                    
                      // Allocate some system memory
                      IntPtr pHData = Marshal.AllocHGlobal(sizeofData);
                    
                      // Fill that memory with the data in 'data'
                      Marshal.StructureToPtr(data, pHData, true);
                    
                      // Create our byte array with the needed number of bytes
                      byte \[\] bytes = new byte\[sizeofData\];
                    
                      // Copy data from the system memory back to our managed array
                      Marshal.Copy(pHData, bytes, 0, sizeofData);
                    
                      // Free our system memory
                      Marshal.FreeHGlobal(pHData);
                    
                      // Finally return the byte array, which was filled with the data
                      // from the system memory, which contained memory filled by the
                      // StructureToPtr call.
                      return bytes;
                    }
                    
                    unsafe private static Data FromByteArrayToData(byte\[\] bytes)
                    {
                      fixed(byte\* pBytes = bytes)
                      {
                        return \*((Data\*) pBytes);
                      }
                    }
                    

                    }
                    }

                    I'd be interested in knowing if there is a "short and sweet" version of the ToByteArray method. It seems like unsafe code could do the conversions, since it has no problems converting a byte array to an object. James Simplicity Rules!

                    T 1 Reply Last reply
                    0
                    • J James T Johnson

                      The binary serializer includes information so that it can deserialize the data correctly. It includes type information (so that it can instantiate the object then load the data into it). Eric Gunnerson pointed out a way to convert from a byte array to the object which is extremely easy; I haven't figured out how to get the byte array as easily though. Here is a test program which shows how it works; compile with the /unsafe compiler switch.

                      using System;
                      using System.Runtime.InteropServices;

                      namespace Test
                      {
                      public struct Data
                      {
                      public int i;
                      public int j;
                      public int k;
                      }

                      public class Driver
                      {
                      public static void Main(string [] args)
                      {
                      byte [] bytes;
                      Data data;
                      Data foo;

                        data.i = 1;
                        data.j = 2;
                        data.k = 3;
                      
                        bytes = ToByteArray(data);
                      
                        foo = FromByteArrayToData(bytes);
                      
                        System.Console.WriteLine("{0}, {1}, {2}", foo.i, foo.j, foo.k);
                      }
                      
                      private static byte\[\] ToByteArray(object data)
                      {
                        // Get size of the object
                        int sizeofData = Marshal.SizeOf(data);
                      
                        // Allocate some system memory
                        IntPtr pHData = Marshal.AllocHGlobal(sizeofData);
                      
                        // Fill that memory with the data in 'data'
                        Marshal.StructureToPtr(data, pHData, true);
                      
                        // Create our byte array with the needed number of bytes
                        byte \[\] bytes = new byte\[sizeofData\];
                      
                        // Copy data from the system memory back to our managed array
                        Marshal.Copy(pHData, bytes, 0, sizeofData);
                      
                        // Free our system memory
                        Marshal.FreeHGlobal(pHData);
                      
                        // Finally return the byte array, which was filled with the data
                        // from the system memory, which contained memory filled by the
                        // StructureToPtr call.
                        return bytes;
                      }
                      
                      unsafe private static Data FromByteArrayToData(byte\[\] bytes)
                      {
                        fixed(byte\* pBytes = bytes)
                        {
                          return \*((Data\*) pBytes);
                        }
                      }
                      

                      }
                      }

                      I'd be interested in knowing if there is a "short and sweet" version of the ToByteArray method. It seems like unsafe code could do the conversions, since it has no problems converting a byte array to an object. James Simplicity Rules!

                      T Offline
                      T Offline
                      tmagoo
                      wrote on last edited by
                      #10

                      Thanks again James. This is what I expected to see out of the byte array. Yes, I would also be interested in knowing a "short and sweet" version of the ToByteArray. Before using this forum, I was trying to do the same thing with C# pointers; but, I could never get what I needed. Then I started looking for a "memcpy" function in C#. I am guessing that the Marshal Object sort of does the same thing as the C++ memcpy function. Thanks again, Tom McDaniel

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups