Esempio n. 1
0
        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);
                }
            }
        }
Esempio n. 2
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.");
            }
        }