无法创建动态字节[]来处理通过异步TCP套接字响应

时间:2018-03-17 15:25:11

标签: c# .net winforms asynchronous tcpclient

在我的C#代码中,我通过TCP链接从DLL接收byte[1024]。 我为此做的代码我在下面附上。

工作流程

  1. 异步数据包在tcp端口收到一个字节数组, 然后将其复制到不同的数组进行处理。

  2. 然后根据收到的数据包处理这个复制的数组 大小(每条消息可以是一个接一个的不同大小)。

  3. 虽然在此期间异步方法收到了另一个数据 应该附加到用于处理数据包的数组。
  4. 问题来自于方法,因为到达TCP端口的异步数据随时会被附加到处理缓冲区数组中,在Copy方法期间它的大小被引用时,多次抛出异常。 在处理一个数据包后,我无法阻止此异步调用。

    // Method to process recieved packet  
    _message.OnRecieve(message);
    

    UI正在更新,并且在用户的操作上再次调用发送和接收方法,其中接收缓冲区数组被新数据覆盖。

    分享一段代码:

    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());
            }
        }
    }
    

0 个答案:

没有答案