Невозможно создать динамический байт[] для обработки данных, полученных через асинхронный ответ TCP-сокета
В моем коде C# я получаю байт[1024] из библиотеки DLL по TCP-ссылке. Код, который я сделал для этого, я прилагаю ниже.
Рабочий процесс
Асинхронный пакет поступает через tcp-порт в массив байтов, который затем копируется в другой массив для обработки.
Затем этот скопированный массив обрабатывается в соответствии с размером полученного пакета(каждое сообщение может быть разного размера одно за другим).
В то время как в то же время асинхронный метод получил еще одни данные, которые должны быть добавлены к массиву, используемому для обработки пакета.
Проблема приходит в методе, поскольку асинхронные данные, поступающие на TCP-порт, добавляются в любое время к массиву буферов обработки, который много раз вызывает исключения, в то время как его размер передается во время методов копирования. Я не могу заблокировать этот асинхронный вызов, как после обработки одного пакета.
/* Method to process recieved packet */ _message.OnRecieve(message);
Пользовательский интерфейс обновляется, и по действию Пользователя снова вызываются методы отправки и получения, где массив буфера приема перезаписывается новыми данными.
Совместное использование фрагмента кода:
Что я уже пробовал:
public class Client { // State object for receiving data from remote device. public class StateObject { // Client socket. public Socket workSocket = null; // Size of receive buffer. public const int BufferSize = 1024; // Receive buffer. public byte[] buffer = new byte[1024]; } public static T ByteArrayToStructure<T>(byte[] bytes) where T : struct { var handle = GCHandle.Alloc(bytes, GCHandleType.Pinned); try { return (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T)); } finally { handle.Free(); } } [StructLayout(LayoutKind.Sequential,Pack = 2)] public struct MessageHeader { public int size; } private static byte[] data = new byte[1024 * 10]; private static void ReceiveCallback(IAsyncResult ar) { try { // Retrieve the state object and the client socket // from the asynchronous state object. StateObject state = (StateObject)ar.AsyncState; Socket client = state.workSocket; // Read data from the remote device. int bytesRead = client.EndReceive(ar); if (bytesRead > 3) { //if data does not contain any data to process if (data.Length == 0) Array.Copy(state.buffer, 0, data, 0, bytesRead); else { //resize data array according to data it contains+data arrived Array.Resize(ref data, data.Length + bytesRead); //if data array contains data and state.buffer arrives with new data Array.Copy(state.buffer, 0, data, data.Length, bytesRead); } // process all data that exist in data array while (data.Length > 2) { byte[] headerbyte = new byte[2]; //read two byes of data contains message length in format IPAddress.NetworkToHostOrder Array.Copy(data, 0, headerbyte, 0, 2); //reverse bytes in headerbyte Array.Reverse(headerbyte); Array.Copy(headerbyte, 0, data, 1, 1); Array.Copy(headerbyte, 1, data, 0, 1); //getting recieved message size from structure MessageHeader header = ByteArrayToStructure<MessageHeader>(data); int packetSize = header.size; //if data contains within data array is partial packet if (data.Length < packetSize) { // Get the rest of the data. client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state); } else { byte[] message = new byte[packetSize]; byte[] remainingData = new byte[data.Length - packetSize]; //copy message data to process into message array Array.Copy(data, 0, message, 0, packetSize); //copy remainng data into a temp array Array.Copy(data, packetSize, remainingData, 0, data.Length - packetSize); //Method to process recieved packet _message.OnRecieve(message); //Removing processed Message from data array by resizing it to of size remaingin data and copying content into it Array.Resize(ref data, remainingData.Length); Array.Copy(remainingData, 0, data, 0, remainingData.Length); } } // Get the rest of the data. client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state); } else { // Create call back for next incoming packet client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state); } } catch (Exception e) { Console.WriteLine(e.ToString()); } } }