public AsyncServerConnectionState(int bufferSize, SocketAsyncEventArgs readEventArgs)
 {
     Buffer = new byte[bufferSize];
     DataStream = new MemoryStream();
     ReadEventArgs = readEventArgs;
     DataProcessingState = new ProcessingState();
 }
Пример #2
0
        //const int PrefixSize = 4;
        private void ProcessReceive(SocketAsyncEventArgs e)
        {
            //single message can be received using several receive operation
            AsyncServerConnectionState state = e.UserToken as AsyncServerConnectionState;

            if (e.BytesTransferred <= 0 || e.SocketError != SocketError.Success)
            { CloseConnection(e); }

            ProcessingState ps = new ProcessingState(e.BytesTransferred, 0,0);
            //int dataRead = e.BytesTransferred;
            //int dataOffset = 0;
            //int restOfData = 0;

            int bufferOffset = state.ReadEventArgs.Offset;
            while (ps.DataRead > 0)
            {
                if (!state.DataSizeReceived)
                {
                    //there is already some data in the buffer
                    if (state.DataStream.Length > 0)
                    {
                        ps.RestOfData = NetworkMessage.HeaderSize - (int)state.DataStream.Length;
                        state.DataStream.Write(state.ReadEventArgs.Buffer,bufferOffset+ ps.DataOffset, ps.RestOfData);
                        ps.DataRead -= ps.RestOfData;
                        ps.DataOffset += ps.RestOfData;
                    }
                    else if (ps.DataRead >= NetworkMessage.HeaderSize)
                    {   //store whole data size prefix
                        state.DataStream.Write(state.ReadEventArgs.Buffer, bufferOffset+ ps.DataOffset, NetworkMessage.HeaderSize);
                        ps.DataRead -= NetworkMessage.HeaderSize;
                        ps.DataOffset += NetworkMessage.HeaderSize;
                    }
                    else
                    {   // store only part of the size prefix
                        state.DataStream.Write(state.ReadEventArgs.Buffer, bufferOffset + ps.DataOffset, ps.DataRead);
                        ps.DataOffset += ps.DataRead;
                        ps.DataRead = 0;
                    }

                    if (state.DataStream.Length == NetworkMessage.HeaderSize)
                    {   //we received data size prefix
                        state.DataSize = BitConverter.ToInt32(state.DataStream.GetBuffer(), 0);
                        if (state.DataSize ==0)
                            Console.Out.Write("aa");
                        state.DataSizeReceived = true;
                        state.DataStream.Position = 0;
                        state.DataStream.SetLength(0);
                    }
                    else
                    {   //we received just part of the headers information
                        //issue another read
                        if (!state.ClientSocket.ReceiveAsync(state.ReadEventArgs))
                            ProcessReceive(state.ReadEventArgs);
                        return;
                    }
                }

                //at this point we know the size of the pending data
                if ((state.DataStream.Length + ps.DataRead) >= state.DataSize)
                {   //we have all the data for this message

                    ps.RestOfData = state.DataSize - (int)state.DataStream.Length;
                    //state.DataStream.Write(state.ReadEventArgs.Buffer, bufferOffset + dataOffset, restOfData);
                    try
                    {
                        state.DataStream.Write(state.ReadEventArgs.Buffer, bufferOffset + ps.DataOffset, ps.RestOfData);
                    }
                    catch (Exception)
                    {
                        Console.Out.WriteLine("state.DataStream.Length = {0}", state.DataStream.Length);
                        Console.Out.WriteLine("dataRead = {0}", ps.DataRead);
                        Console.Out.WriteLine("state.DataSize = {0}", state.DataSize);
                        Console.WriteLine("1");
                        throw;
                    }

                    if (MessageReceived != null)
                    {
                        byte[] messageBytes = new byte[state.DataSize];
                        Buffer.BlockCopy(state.DataStream.GetBuffer(), 0, messageBytes, 0, state.DataSize);
                        MessageReceived(this, new MessageReceivedEventArgs(messageBytes, state.DataSize));
                    }

                    ps.DataOffset += ps.RestOfData;
                    ps.DataRead -= ps.RestOfData;
                    state.DataStream.SetLength(0);
                    state.DataStream.Position = 0;
                    state.DataSizeReceived = false;
                    state.DataSize = 0;

                    if (ps.DataRead == 0)
                    {
                        if (!state.ClientSocket.ReceiveAsync(state.ReadEventArgs))
                            ProcessReceive(state.ReadEventArgs);
                        return;
                    }
                    else
                        continue;
                }
                else
                {   //there is still data pending, store what we've
                    //received and issue another BeginReceive
                    state.DataStream.Write(state.ReadEventArgs.Buffer, bufferOffset + ps.DataOffset, ps.DataRead);

                    if (!state.ClientSocket.ReceiveAsync(state.ReadEventArgs))
                        ProcessReceive(state.ReadEventArgs);

                    ps.DataRead = 0;
                }
            }
        }