private void ProcessReceivedData(ref MessageAccumulator msgAccumulator, byte[] rawData, int dataLength) { byte[] workingBuffer; int readIndex; //int newDataLength; bool hasMoreData; hasMoreData = false; readIndex = 0; do { workingBuffer = (msgAccumulator.Stage == MessageAccumulator.AccumatingStage.HEADER) ? msgAccumulator.Header : msgAccumulator.Payload; int neededBytes = msgAccumulator.DesiredBytes - msgAccumulator.ReceivedBytes; int bytesToCopy = (dataLength > neededBytes) ? neededBytes : dataLength; Array.Copy(rawData, readIndex, workingBuffer, msgAccumulator.ReceivedBytes, bytesToCopy); msgAccumulator.ReceivedBytes += bytesToCopy; readIndex += bytesToCopy; dataLength -= bytesToCopy; hasMoreData = dataLength != 0; if (msgAccumulator.ReceivedBytes == msgAccumulator.DesiredBytes) { if (msgAccumulator.Stage == MessageAccumulator.AccumatingStage.HEADER) { DecodeHeader(msgAccumulator.MessageHeader, msgAccumulator.Header); msgAccumulator.Payload = new byte[msgAccumulator.MessageHeader.Length]; msgAccumulator.Stage = MessageAccumulator.AccumatingStage.BODY; msgAccumulator.DesiredBytes = msgAccumulator.MessageHeader.Length; msgAccumulator.ReceivedBytes = 0; } else { OnMessageReceived(msgAccumulator.MessageHeader.EncodingType, msgAccumulator.MessageHeader.EncodingVersion, msgAccumulator.Payload); msgAccumulator = new MessageAccumulator(); } } } while (hasMoreData); }
private void ReadCallback(IAsyncResult asyncResult) { try { ReadContext readContext = (ReadContext)asyncResult.AsyncState; byte[] rawData = readContext.Data; int bytesReceived = 0; try { bytesReceived = ReadStream.EndRead(asyncResult); } catch (Exception) { bytesReceived = 0; } if (bytesReceived == 0) { // Read as failed (bytes received == 0 or exception in EndRead) ReadFailed(readContext); return; } MessageAccumulator msgAcc = readContext.Accumulator; ProcessReceivedData(ref msgAcc, rawData, bytesReceived); readContext.Accumulator = msgAcc; //continue to read if it's not closed. lock (this) { if (closed) { return; } } ReadStream.BeginRead(readContext.Data, 0, readContext.Data.Length, new AsyncCallback(ReadCallback), readContext); } catch (Exception e) { log.Error(e); } }
public ReadContext(int dataBufferLength, long connectionVersion) { msgAccumulator = new MessageAccumulator(); rawData = new byte[dataBufferLength]; this.connectionVersion = connectionVersion; }
private void DecodeHeader(MessageAccumulator.DecodedMessageHeader decodedMessageHeader, byte[] encodedMessageHeader) { short protocolTypeNet = BitConverter.ToInt16(encodedMessageHeader, 0); short protocolVerionNet = BitConverter.ToInt16(encodedMessageHeader, 2); int messageLengthNet = BitConverter.ToInt32(encodedMessageHeader, 4); decodedMessageHeader.EncodingType = IPAddress.NetworkToHostOrder(protocolTypeNet); decodedMessageHeader.EncodingVersion = IPAddress.NetworkToHostOrder(protocolVerionNet); decodedMessageHeader.Length = IPAddress.NetworkToHostOrder(messageLengthNet); }