示例#1
0
        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.");
            }
        }