private ServiceResult DoReadComplete(SocketAsyncEventArgs e)
{
// complete operation.
int bytesRead = e.BytesTransferred;
lock (m_socketLock)
{
BufferManager.UnlockBuffer(m_receiveBuffer);
}
if (bytesRead == 0)
{
// free the empty receive buffer.
if (m_receiveBuffer != null)
{
m_bufferManager.ReturnBuffer(m_receiveBuffer, "DoReadComplete");
m_receiveBuffer = null;
}
return ServiceResult.Good;
}
// Utils.Trace("Bytes read: {0}", bytesRead);
m_bytesReceived += bytesRead;
// check if more data left to read.
if (m_bytesReceived < m_bytesToReceive)
{
ReadNextBlock();
return ServiceResult.Good;
}
// start reading the message body.
if (m_incomingMessageSize < 0)
{
m_incomingMessageSize = BitConverter.ToInt32(m_receiveBuffer, 4);
if (m_incomingMessageSize <= 0 || m_incomingMessageSize > m_receiveBufferSize)
{
Utils.Trace(
"BadTcpMessageTooLarge: BufferSize={0}; MessageSize={1}",
m_receiveBufferSize,
m_incomingMessageSize);
return ServiceResult.Create(
StatusCodes.BadTcpMessageTooLarge,
"Messages size {1} bytes is too large for buffer of size {0}.",
m_receiveBufferSize,
m_incomingMessageSize);
}
// set up buffer for reading the message body.
m_bytesToReceive = m_incomingMessageSize;
ReadNextBlock();
return ServiceResult.Good;
}
// notify the sink.
if (m_sink != null)
{
try
{
// send notification (implementor responsible for freeing buffer) on success.
ArraySegment<byte> messageChunk = new ArraySegment<byte>(m_receiveBuffer, 0, m_incomingMessageSize);
// must allocate a new buffer for the next message.
m_receiveBuffer = null;
m_sink.OnMessageReceived(this, messageChunk);
}
catch (Exception ex)
{
Utils.Trace(ex, "Unexpected error invoking OnMessageReceived callback.");
}
}
// free the receive buffer.
if (m_receiveBuffer != null)
{
m_bufferManager.ReturnBuffer(m_receiveBuffer, "DoReadComplete");
m_receiveBuffer = null;
}
// start receiving next message.
ReadNextMessage();
return ServiceResult.Good;
}