ashish jaiswal

ashish jaiswal

  • NA
  • 12
  • 3.1k

Unable to create a dynamic byte[] to process data received

Mar 19 2018 1:11 AM
In my C# code I am receiving a byte[1024] from a DLL through TCP link. Code I did for this I am attaching below.
 
The workflow is
  1. An asynchronous packet gets received at tcp port into a byte array, which then gets copied to a different array for processing.
  2. This copied array then gets processed according to received packet size(each message could be of different size one behind another).
  3. While in the meantime async method received another data which should get appended to array used for processing packet.
Problem coming is being method as asynchronous data arriving at TCP port is getting appended anytime to the processing buffer array which many times throws exceptions while its size is getting referred during Copy methods. I am unable to block this async call as after processing one packet.
 
/* Method to process recieved packet */ _message.OnRecieve(message);
 
UI is getting updated and on user's action again the send and receive methods getting called where receive buffer array gets overwritten with new data.
 
Sharing piece of code: 
  1. public class Client  
  2. {  
  3.     // State object for receiving data from remote device.  
  4.     public class StateObject  
  5.     {  
  6.         // Client socket.  
  7.         public Socket workSocket = null;  
  8.         // Size of receive buffer.  
  9.         public const int BufferSize = 1024;  
  10.         // Receive buffer.  
  11.         public byte[] buffer = new byte[1024];     
  12.     }  
  13.   
  14.     public static T ByteArrayToStructure(byte[] bytes) where T : struct  
  15.     {  
  16.         var handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);  
  17.         try  
  18.         {  
  19.             return (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));  
  20.         }  
  21.         finally  
  22.         {  
  23.             handle.Free();  
  24.         }  
  25.     }  
  26.   
  27.     [StructLayout(LayoutKind.Sequential,Pack = 2)]  
  28.     public struct MessageHeader  
  29.     {  
  30.         public int size;  
  31.     }  
  32.   
  33.     private static byte[] data = new byte[1024 * 10];  
  34.   
  35.     private static void ReceiveCallback(IAsyncResult ar)  
  36.     {  
  37.         try  
  38.         {  
  39.             // Retrieve the state object and the client socket   
  40.             // from the asynchronous state object.  
  41.             StateObject state = (StateObject)ar.AsyncState;  
  42.             Socket client = state.workSocket;  
  43.   
  44.             // Read data from the remote device.  
  45.             int bytesRead = client.EndReceive(ar);  
  46.   
  47.             if (bytesRead > 3)  
  48.             {  
  49.                 //if data does not contain any data to process   
  50.                 if (data.Length == 0)  
  51.                     Array.Copy(state.buffer, 0, data, 0, bytesRead);  
  52.                 else  
  53.                 {  
  54.                     //resize data array according to data it contains+data arrived  
  55.                     Array.Resize(ref data, data.Length + bytesRead);  
  56.                     //if data array contains data and state.buffer arrives with new data   
  57.                     Array.Copy(state.buffer, 0, data, data.Length, bytesRead);  
  58.                 }  
  59.   
  60.                 // process all data that exist in data array    
  61.                 while (data.Length > 2)  
  62.                 {  
  63.                     byte[] headerbyte = new byte[2];  
  64.   
  65.                     //read two byes of data contains message length in format IPAddress.NetworkToHostOrder  
  66.                     Array.Copy(data, 0, headerbyte, 0, 2);  
  67.   
  68.                     //reverse bytes in headerbyte  
  69.                     Array.Reverse(headerbyte);  
  70.   
  71.                     Array.Copy(headerbyte, 0, data, 1, 1);  
  72.                     Array.Copy(headerbyte, 1, data, 0, 1);  
  73.   
  74.                     //getting recieved message size from structure  
  75.                     MessageHeader header = ByteArrayToStructure(data);  
  76.   
  77.                     int packetSize = header.size;  
  78.   
  79.                     //if data contains within data array is partial packet  
  80.                     if (data.Length < packetSize)  
  81.                     {  
  82.                         // Get the rest of the data.  
  83.                         client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,  
  84.                             new AsyncCallback(ReceiveCallback), state);  
  85.                     }  
  86.                     else  
  87.                     {  
  88.                         byte[] message = new byte[packetSize];  
  89.                         byte[] remainingData = new byte[data.Length - packetSize];  
  90.   
  91.                         //copy message data to process into message array  
  92.                         Array.Copy(data, 0, message, 0, packetSize);  
  93.                         //copy remainng data into a temp array  
  94.                         Array.Copy(data, packetSize, remainingData, 0, data.Length - packetSize);  
  95.   
  96.                         //Method to process recieved packet  
  97.                         _message.OnRecieve(message);  
  98.   
  99.                         //Removing processed Message from data array by resizing it to of size remaingin data and copying content into it  
  100.                         Array.Resize(ref data, remainingData.Length);  
  101.                         Array.Copy(remainingData, 0, data, 0, remainingData.Length);  
  102.                     }  
  103.                 }  
  104.                 // Get the rest of the data.  
  105.                 client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,  
  106.                     new AsyncCallback(ReceiveCallback), state);  
  107.             }  
  108.             else  
  109.             {  
  110.                 // Create call back for next incoming packet  
  111.                 client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,  
  112.                     new AsyncCallback(ReceiveCallback), state);  
  113.             }  
  114.         }  
  115.         catch (Exception e)  
  116.         {  
  117.             Console.WriteLine(e.ToString());  
  118.         }  
  119.     }  
  120. }