locked
In C#, how can I send a binary packet structure with Socket.Send?

    Question

  • Hello,

    I am trying to send a binary packet structure using Socket.send.  I have defined the packet using "StructLayout" and "FieldOffset" in a manner similar to the following:

    [StructLayout(LayoutKind.Explicit, Size = 6)]

    public class PacketHdr

    { [FieldOffset(0)]public short PacketType;

    [FieldOffset(2)]public int PacketLength; }

    After I create an instance of PacketHdr, I need to reference it as "byte [ ]" to send it out using "Socket.Send", since the buffer parameter of Socket.Send is defined as "byte [ ]" as follows:

         int Socket.Send(byte [ ] buffer, int offset, int size, ...

    How can I reference the packet as "byte [ ]"?

    This is trivial in C++, but I have not been able to find an example in C#.

    Thank you for your help.

    Bill Welch

     

     

    Thursday, January 11, 2007 2:13 PM

Answers

  • include these 2 lines at the top of the class file:

    using System.Runtime.Serialization;

    using System.Runtime.Serialization.Formatter.Binary;

    Here your class goes:

    [Serializable]
        public class PacketHdr
        {
            private short packetType;
            private int packetLength;

            public PacketHdr(short packetType, int packetLength)
            {
                this.packetType = packetType;
                this.packetLength = packetLength;
            }
        }

     

    Here Function to do the Conversion:

    From object to bytes:

    private byte[] GetPacketBytes(PacketHdr packetHdr)
            {
                MemoryStream ms = new MemoryStream();
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(ms, packetHdr);
                return ms.ToArray();
            }

    From Byes to object:

            private PacketHdr GetPacketObject(byte[] packetBytes)
            {
                MemoryStream ms = new MemoryStream();
                ms.Write(packetBytes, 0, packetBytes.Length);
                ms.Position = 0;
                BinaryFormatter formatter = new BinaryFormatter();
                return formatter.Deserialize(ms) as PacketHdr;
            }

    Usage:

    PacketHdr p = new PacketHdr(1, 2);

    byte[] packetBytes = GetPacketBytes(p); // Write these bytes on Network;

    Read the bytes from the Network and contruct the object from the following line:

    PacketHdr p1 = GetPacketObject(packetBytes);

    Make sure to Receive all the bytes from the Network before you Decerialize bytes back to object otherwise wou;ll get an exception. So you have to make a check that how many bytes are sending and how many bytes you have to receive for a successful deserialization.

    I hope this will help.

    Best Regards,

    Rizwan aka RizwanSharp

    Thursday, January 11, 2007 4:46 PM

All replies

  • Hi

    Serialize your object to get byte[] using the following code



    MemoryStream ms =
    new MemoryStream();
    BinaryFormatter formatter = new BinaryFormatter();
    formatter.AssemblyFormat = FormatterAssemblyStyle.Simple;
    formatter.TypeFormat = FormatterTypeStyle.TypesWhenNeeded;
    formatter.Serialize(ms,<objPacketHdr>);
    return ms.GetBuffer(); //THIS WILL RETURN BYTE[] WHICH YOU WANT

     

    Then when you receive this byte[] then Deseiralize it to get actual object,



    MemoryStream ms =
    new MemoryStream(bytes, offset, count); //HERE BYTES IS BYTE[] YOU HAVE RECEIVED
    BinaryFormatter formatter =
    new BinaryFormatter();
    formatter.AssemblyFormat = FormatterAssemblyStyle.Simple;
    formatter.TypeFormat = FormatterTypeStyle.TypesWhenNeeded;
    PacketHdr objPacketHdr = (PacketHdr)formatter.Deserialize(ms);

     

    PLEASE NOTE: You will need to mark your class with [Serializable] attribute to serialize it.

    HTH,

    Thursday, January 11, 2007 3:09 PM
  • include these 2 lines at the top of the class file:

    using System.Runtime.Serialization;

    using System.Runtime.Serialization.Formatter.Binary;

    Here your class goes:

    [Serializable]
        public class PacketHdr
        {
            private short packetType;
            private int packetLength;

            public PacketHdr(short packetType, int packetLength)
            {
                this.packetType = packetType;
                this.packetLength = packetLength;
            }
        }

     

    Here Function to do the Conversion:

    From object to bytes:

    private byte[] GetPacketBytes(PacketHdr packetHdr)
            {
                MemoryStream ms = new MemoryStream();
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(ms, packetHdr);
                return ms.ToArray();
            }

    From Byes to object:

            private PacketHdr GetPacketObject(byte[] packetBytes)
            {
                MemoryStream ms = new MemoryStream();
                ms.Write(packetBytes, 0, packetBytes.Length);
                ms.Position = 0;
                BinaryFormatter formatter = new BinaryFormatter();
                return formatter.Deserialize(ms) as PacketHdr;
            }

    Usage:

    PacketHdr p = new PacketHdr(1, 2);

    byte[] packetBytes = GetPacketBytes(p); // Write these bytes on Network;

    Read the bytes from the Network and contruct the object from the following line:

    PacketHdr p1 = GetPacketObject(packetBytes);

    Make sure to Receive all the bytes from the Network before you Decerialize bytes back to object otherwise wou;ll get an exception. So you have to make a check that how many bytes are sending and how many bytes you have to receive for a successful deserialization.

    I hope this will help.

    Best Regards,

    Rizwan aka RizwanSharp

    Thursday, January 11, 2007 4:46 PM