Exemple #1
0
        private void ProcessSendQueue(Socket handler)
        {
            while (_isConnected)
            {
                // Get the next buffer from the queue
                var socketAsyncEventArgs = _sendBufferQueue.Dequeue();
                if (socketAsyncEventArgs == null)
                {
                    continue;
                }

                _sendBufferReset.Reset();

                // Do the send
                TryUnsafeSocketOperation(_socket, SocketAsyncOperation.Send, socketAsyncEventArgs);

                if (!_sendBufferReset.WaitOne(_communicationTimeout))
                {
                    HandleCommunicationError(_socket, new TimeoutException("The connection timed out before the send acknowledgement was received"));
                    return;
                }
            }
        }
Exemple #2
0
        private void ProcessReceivedMessage(Socket handler)
        {
            int bytesToRead = -1;
            int threadId    = -1;

            int controlBytesOffset = 0;

            byte[] protocolBuffer = new byte[ProtocolHelper.ControlBytesPlaceholder.Length];
            byte[] resultBuffer   = null;

            // Loop until socket is done
            while (_isConnected)
            {
                // Get the next buffer from the queue
                var socketAsyncEventArgs = _receiveBufferQueue.Dequeue();
                if (socketAsyncEventArgs == null)
                {
                    continue;
                }

                var buffer    = socketAsyncEventArgs.Buffer;
                int bytesRead = socketAsyncEventArgs.BytesTransferred;

                int currentOffset = 0;

                while (currentOffset < bytesRead)
                {
                    // Check if we need to get our control byte values
                    if (bytesToRead == -1)
                    {
                        var controlBytesNeeded    = ProtocolHelper.ControlBytesPlaceholder.Length - controlBytesOffset;
                        var controlBytesAvailable = bytesRead - currentOffset;

                        var controlBytesToCopy = Math.Min(controlBytesNeeded, controlBytesAvailable);

                        // Copy bytes to control buffer
                        Buffer.BlockCopy(buffer, currentOffset, protocolBuffer, controlBytesOffset, controlBytesToCopy);

                        controlBytesOffset += controlBytesToCopy;
                        currentOffset      += controlBytesToCopy;

                        // Check if done
                        if (controlBytesOffset == ProtocolHelper.ControlBytesPlaceholder.Length)
                        {
                            // Parse out control bytes
                            ProtocolHelper.ExtractControlBytes(protocolBuffer, out bytesToRead, out threadId);

                            // Reset control bytes offset
                            controlBytesOffset = 0;

                            // Ensure message is not larger than maximum message size
                            if (bytesToRead > _maxMessageSize)
                            {
                                HandleCommunicationError(handler, new InvalidOperationException(string.Format("message of length {0} exceeds maximum message length of {1}", bytesToRead, _maxMessageSize)));
                                return;
                            }
                        }

                        // Continue the loop
                        continue;
                    }

                    // Have control bytes, get message bytes

                    // SPECIAL CASE: if empty message, skip a bunch of stuff
                    if (bytesToRead != 0)
                    {
                        // Initialize buffer if needed
                        if (resultBuffer == null)
                        {
                            resultBuffer = new byte[bytesToRead];
                        }

                        var bytesAvailable = bytesRead - currentOffset;

                        var bytesToCopy = Math.Min(bytesToRead, bytesAvailable);

                        // Copy bytes to buffer
                        Buffer.BlockCopy(buffer, currentOffset, resultBuffer, resultBuffer.Length - bytesToRead, bytesToCopy);

                        currentOffset += bytesToCopy;
                        bytesToRead   -= bytesToCopy;
                    }

                    // Check if we're done
                    if (bytesToRead == 0)
                    {
                        if (resultBuffer != null)
                        {
                            // Done, add to complete received messages
                            CompleteMessage(handler, threadId, resultBuffer);

                            // Reset message state
                            resultBuffer = null;
                        }

                        bytesToRead = -1;
                        threadId    = -1;

                        _lastResponse = DateTime.UtcNow;
                    }
                }

                _socketAsyncEventArgsReceivePool.Push(socketAsyncEventArgs);
            }
        }
Exemple #3
0
        private void ProcessReceivedMessage(ConnectedClient connectedClient)
        {
            int bytesToRead = -1;
            int threadId    = -1;

            int availableTest      = 0;
            int controlBytesOffset = 0;

            byte[] protocolBuffer = new byte[_controlBytesPlaceholder.Length];
            byte[] resultBuffer   = null;

            var handler = connectedClient.Socket;

            BlockingQueue <SocketAsyncEventArgs> receiveBufferQueue = null;

            _currentlyConnectedClientsReceiveQueuesLock.EnterReadLock();
            try
            {
                if (!_currentlyConnectedClientsReceiveQueues.TryGetValue(handler, out receiveBufferQueue))
                {
                    // Peace out!
                    return;
                }
            }
            finally
            {
                _currentlyConnectedClientsReceiveQueuesLock.ExitReadLock();
            }

            // Loop until socket is done
            while (_isListening)
            {
                // If the socket is disposed, we're done
                try
                {
                    availableTest = handler.Available;
                }
                catch (ObjectDisposedException)
                {
                    // Peace out!
                    return;
                }

                // Get the next buffer from the queue
                var socketAsyncEventArgs = receiveBufferQueue.Dequeue();
                if (socketAsyncEventArgs == null)
                {
                    continue;
                }

                var buffer    = socketAsyncEventArgs.Buffer;
                int bytesRead = socketAsyncEventArgs.BytesTransferred;

                int currentOffset = 0;

                while (currentOffset < bytesRead)
                {
                    // Check if we need to get our control byte values
                    if (bytesToRead == -1)
                    {
                        var controlBytesNeeded    = _controlBytesPlaceholder.Length - controlBytesOffset;
                        var controlBytesAvailable = bytesRead - currentOffset;

                        var controlBytesToCopy = Math.Min(controlBytesNeeded, controlBytesAvailable);

                        // Copy bytes to control buffer
                        Buffer.BlockCopy(buffer, currentOffset, protocolBuffer, controlBytesOffset, controlBytesToCopy);

                        controlBytesOffset += controlBytesToCopy;
                        currentOffset      += controlBytesToCopy;

                        // Check if done
                        if (controlBytesOffset == _controlBytesPlaceholder.Length)
                        {
                            // Parse out control bytes
                            ExtractControlBytes(protocolBuffer, out bytesToRead, out threadId);

                            // Reset control bytes offset
                            controlBytesOffset = 0;

                            // Ensure message is not larger than maximum message size
                            if (bytesToRead > _maxMessageSize)
                            {
                                HandleCommunicationError(handler, new InvalidOperationException(string.Format("message of length {0} exceeds maximum message length of {1}", bytesToRead, _maxMessageSize)));
                                return;
                            }
                        }

                        // Continue the loop
                        continue;
                    }

                    // Have control bytes, get message bytes

                    // SPECIAL CASE: if empty message, skip a bunch of stuff
                    if (bytesToRead != 0)
                    {
                        // Initialize buffer if needed
                        if (resultBuffer == null)
                        {
                            resultBuffer = new byte[bytesToRead];
                        }

                        var bytesAvailable = bytesRead - currentOffset;

                        var bytesToCopy = Math.Min(bytesToRead, bytesAvailable);

                        // Copy bytes to buffer
                        Buffer.BlockCopy(buffer, currentOffset, resultBuffer, resultBuffer.Length - bytesToRead, bytesToCopy);

                        currentOffset += bytesToCopy;
                        bytesToRead   -= bytesToCopy;
                    }

                    // Check if we're done
                    if (bytesToRead == 0)
                    {
                        if (resultBuffer != null)
                        {
                            // Done, add to complete received messages
                            CompleteMessage(handler, threadId, resultBuffer);

                            // Reset message state
                            resultBuffer = null;
                        }

                        bytesToRead = -1;
                        threadId    = -1;

                        connectedClient.LastResponse = DateTime.UtcNow;
                    }
                }

                // Push the buffer back onto the pool
                _socketAsyncEventArgsReceivePool.Push(socketAsyncEventArgs);
            }
        }
Exemple #4
0
        private void ProcessReceivedMessage(MessageState messageState)
        {
            int currentOffset = 0;
            int bytesRead     = 0;

            while (_isDoingSomething)
            {
                // Check if we need a buffer
                if (messageState.Buffer == null)
                {
                    // Get the next buffer
                    BlockingQueue <KeyValuePair <byte[], int> > queue = null;
                    _receiveBufferQueueLock.EnterReadLock();
                    try
                    {
                        if (!_receiveBufferQueue.TryGetValue(messageState.Handler.GetHashCode(), out queue))
                        {
                            throw new Exception("FATAL: No receive queue created for current socket");
                        }
                    }
                    finally
                    {
                        _receiveBufferQueueLock.ExitReadLock();
                    }

                    var receiveBufferEntry = queue.Dequeue();
                    messageState.Buffer = receiveBufferEntry.Key;
                    currentOffset       = 0;
                    bytesRead           = receiveBufferEntry.Value;
                }

                // Check if we need to get our control byte values
                if (messageState.TotalBytesToRead == -1)
                {
                    // We do, see if we have enough bytes received to get them
                    if (currentOffset + _controlBytesPlaceholder.Length > currentOffset + bytesRead)
                    {
                        // We don't yet have enough bytes to read the control bytes, so get more bytes

                        // Loop until we have enough data to proceed
                        int bytesNeeded = _controlBytesPlaceholder.Length - bytesRead;
                        while (bytesNeeded > 0)
                        {
                            // Combine the buffers
                            BlockingQueue <KeyValuePair <byte[], int> > queue = null;
                            _receiveBufferQueueLock.EnterReadLock();
                            try
                            {
                                if (!_receiveBufferQueue.TryGetValue(messageState.Handler.GetHashCode(), out queue))
                                {
                                    throw new Exception("FATAL: No receive queue created for current socket");
                                }
                            }
                            finally
                            {
                                _receiveBufferQueueLock.ExitReadLock();
                            }

                            var nextBufferEntry = queue.Dequeue();
                            var combinedBuffer  = new byte[bytesRead + nextBufferEntry.Value];
                            Buffer.BlockCopy(messageState.Buffer, currentOffset, combinedBuffer, 0, bytesRead);
                            Buffer.BlockCopy(nextBufferEntry.Key, 0, combinedBuffer, bytesRead, nextBufferEntry.Value);
                            // Set the new combined buffer and appropriate bytes read
                            messageState.Buffer = combinedBuffer;
                            // Reset bytes read and current offset
                            currentOffset = 0;
                            bytesRead     = combinedBuffer.Length;
                            // Subtract from bytes needed
                            bytesNeeded -= nextBufferEntry.Value;
                        }
                    }

                    // Parse out control bytes
                    ExtractControlBytes(messageState.Buffer, currentOffset, out messageState.TotalBytesToRead, out messageState.ThreadId);
                    // Offset the index by the control bytes
                    currentOffset += _controlBytesPlaceholder.Length;
                    // Take control bytes off of bytes read
                    bytesRead -= _controlBytesPlaceholder.Length;
                }

                int numberOfBytesToRead = Math.Min(bytesRead, messageState.TotalBytesToRead);
                messageState.Data.Write(messageState.Buffer, currentOffset, numberOfBytesToRead);

                // Set total bytes read
                int originalTotalBytesToRead = messageState.TotalBytesToRead;
                messageState.TotalBytesToRead -= numberOfBytesToRead;

                // Check if we're done
                if (messageState.TotalBytesToRead == 0)
                {
                    // Done, add to complete received messages
                    CompleteMessage(messageState.Handler, messageState.ThreadId, messageState.Data.ToArray());
                }

                // Check if we have an overlapping message frame in our message AKA if the bytesRead was larger than the total bytes to read
                if (bytesRead > originalTotalBytesToRead)
                {
                    // Get the number of bytes remaining to be read
                    int bytesRemaining = bytesRead - numberOfBytesToRead;

                    // Set total bytes to read to default
                    messageState.TotalBytesToRead = -1;
                    // Dispose and reinitialize data stream
                    messageState.Data.Dispose();
                    messageState.Data = new MemoryStream();

                    // Now we have the next message, so recursively process it
                    currentOffset += numberOfBytesToRead;
                    bytesRead      = bytesRemaining;
                    continue;
                }

                // Only create a new message state if we are done with this message
                if (!(bytesRead < originalTotalBytesToRead))
                {
                    // Get new state for the next message but transfer over handler
                    Socket handler = messageState.Handler;
                    messageState.Data.Dispose();
                    messageState.Data             = new MemoryStream();
                    messageState.Handler          = handler;
                    messageState.TotalBytesToRead = -1;
                    messageState.ThreadId         = -1;
                }

                // Reset buffer for next message
                _bufferPool.Push(messageState.Buffer);
                messageState.Buffer = null;
            }
        }