public AsyncServerConnectionState(int bufferSize, SocketAsyncEventArgs readEventArgs) { Buffer = new byte[bufferSize]; DataStream = new MemoryStream(); ReadEventArgs = readEventArgs; DataProcessingState = new ProcessingState(); }
//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; } } }