private IEnumerator <bool> GetReceiveEnumerator(ParameterlessDelegate callback) { _receiveArgs.UserToken = callback; while (true) { if (_socket.ReceiveAsync(_receiveArgs)) { yield return(false); } if (!ValidateCompletedEvent(_receiveArgs, SocketAsyncOperation.Receive)) { yield break; } if (_receiveArgs.BytesTransferred == 0) { SetError(SocketError.ConnectionReset); yield break; } if (_operationType != OperationType.RoundTrip) { SetError(new InvalidOperationException("Received data when no round trip operation was pending.")); yield break; } int position = _receiveArgs.Offset; int count = _receiveArgs.BytesTransferred; if (!_responseHeader.IsComplete) { position += _responseHeader.Read(_receiveArgs.Buffer, position, count - position); if (!_responseHeader.IsComplete || count == position) { continue; } } if (_responseData == null) { _responseData = AsyncSocketClient.MemoryPool.Borrow(); } int countAvailable = count - position; int countNeeded = _responseHeader.MessageDataLength - (int)_responseData.Item.Length; if (countNeeded <= countAvailable) { _responseData.Item.Write(_receiveArgs.Buffer, position, countNeeded); _responseData.Item.Seek(0, SeekOrigin.Begin); if (_responseHeader.MessageLength == ServerMessage.EmptyReplyMessageLength && ServerMessage.IsEmptyMessage(_responseData.Item.GetBuffer(), (int)_responseData.Item.Position, (int)_responseHeader.MessageLength)) { _responseData.Dispose(); _responseData = null; } _responseReceived = true; } else { _responseData.Item.Write(_receiveArgs.Buffer, position, countAvailable); } if (IsOperationComplete) { yield return(true); } } }
private IEnumerator <bool> GetReceiveEnumerator(ParameterlessDelegate callback) { _receiveArgs.UserToken = callback; try { while (true) { if (_error != null) { yield break; } // note - it seems this is necessary because of a bug in the SendAsync function // see - http://social.msdn.microsoft.com/Forums/en-IE/ncl/thread/40fe397c-b1da-428e-a355-ee5a6b0b4d2c Thread.MemoryBarrier(); LogDebugStep("Receiving..."); yield return(!_socket.ReceiveAsync(_receiveArgs)); LogDebugStep("Receive Complete."); if (!ValidateCompletedEvent(_receiveArgs, SocketAsyncOperation.Receive)) { yield break; } if (_receiveArgs.BytesTransferred == 0) { SetError(SocketError.ConnectionReset); yield break; } if (_operationType != OperationType.RoundTrip) { SetError(new InvalidOperationException("Received data when no round trip operation was pending.")); yield break; } int position = _receiveArgs.Offset; int count = _receiveArgs.BytesTransferred; if (!_responseHeader.IsComplete) { position += _responseHeader.Read(_receiveArgs.Buffer, position, count - position); if (!_responseHeader.IsComplete || count == position) { if (_log.IsDebugEnabled) { LogDebugStep(string.Format("Received partial header {0:###,##0} bytes", count - position)); } continue; } } if (_responseData == null) { _responseData = AsyncSocketClient.MemoryPool.Borrow(); } int countAvailable = count - position; int countNeeded = _responseHeader.MessageDataLength - (int)_responseData.Item.Length; if (countNeeded <= countAvailable) { _responseData.Item.Write(_receiveArgs.Buffer, position, countNeeded); _responseData.Item.Seek(0, SeekOrigin.Begin); if (_responseHeader.MessageLength == ServerMessage.EmptyReplyMessageLength && ServerMessage.IsEmptyMessage(_responseData.Item.GetBuffer(), (int)_responseData.Item.Position, _responseHeader.MessageLength)) { _responseData.Dispose(); _responseData = null; } _responseReceived = true; } else { _responseData.Item.Write(_receiveArgs.Buffer, position, countAvailable); } if (_log.IsDebugEnabled) { LogDebugStep(countAvailable + " of " + countNeeded + " bytes received. " + (countNeeded - countAvailable) + " bytes remaining. Complete=" + IsOperationComplete); } } } finally { LogDebugStep("Receive Loop Ended."); } }