tags:

views:

263

answers:

3

I'm wondering if there are any good guides or books that explain the best way to handle network packet communication in C#?

Right now I'm using a structure and a method that generates a byte array based on values of the structure.

Is there a simpler way to do this? Or even a better way?

public struct hotline_transaction
{
        private int transaction_id;
        private short task_number;
        private int error_code;
        private int data_length;
        private int data_length2;

...

     public int Transaction_id
     {
      get
      {
       return IPAddress.HostToNetworkOrder(transaction_id);
      }
      set
      {
       transaction_id = value;
      }
     }

...

     public byte[] GetBytes()
     {
      List<byte> buffer = new List<byte>();
      buffer.Add(0); // reserved
      buffer.Add(0); // request = 0

      buffer.AddRange(BitConverter.GetBytes(Task_number));
      buffer.AddRange(BitConverter.GetBytes(Transaction_id));
      buffer.AddRange(BitConverter.GetBytes(error_code));


      buffer.AddRange(BitConverter.GetBytes(Data_length));

      buffer.AddRange(subBuffer.ToArray());

      return buffer.ToArray(); // return byte array for network sending
     }
}

Beyond that is there a good guide or article on the best practice of parsing network data into usable structures / classes?

+2  A: 

Well, rather than GetBytes(), I'd be tempted to use a Write(Stream), in case it is big... but in the general case there are serialization APIs for this... I'd mention my own, but I think people get bored of hearing it.

IMO, hotline_transaction looks more like a class (than a struct) to me, btw.

Marc Gravell
+1 for class/struct distinction. Mutable structs are evil evil evil.
Bryan Watts
I'm not sure why I used a structure, it could easily be a class and actually after looking at the differences between structures and classes making this a class makes more sense.
Josiah Peters
+2  A: 

Have you heard of google protocol buffers?

protocol buffers is the name of the binary serialization format used by Google for much of their data communications. It is designed to be:

small in size - efficient data storage (far smaller than xml) cheap to process - both at the client and server platform independent - portable between different programming architectures extensible - to add new data to old messages

instanceofTom
Now, if only there was a C# implementation of that API which could be retro-fitted to an existing class simply by adding a few attributes... (cough) ;-p
Marc Gravell
A: 

You should probably use a BinaryWriter for this, and rather than returning byte[], you should pass a BinaryWriter to the serialization code, i.e.,

public void WriteBytes(BinaryWriter writer)
{
    writer.Write((byte)0); // reserved
    writer.Write((byte)0); // request = 0

    writer.Write(Task_number);
    writer.Write(Transaction_id);
    writer.Write(error_code);

    writer.Write(Data_length);

    subBuffer.WriteBytes(writer);
}

You can easily wrap an existing Stream with a BinaryWriter. If you really need to get a byte[] somehow, you can use a MemoryStream as a backing stream, and call ToArray when you're done.

Ruben