Пример #1
0
        /// <summary>
        /// Reads the next block of data from the socket.
        /// </summary>
        private void ReadNextBlock()
        {
            Socket socket = null;

            // check if already closed.
            lock (m_socketLock) {
                if (m_socket == null)
                {
                    if (m_receiveBuffer != null)
                    {
                        m_bufferManager.ReturnBuffer(m_receiveBuffer, "ReadNextBlock");
                        m_receiveBuffer = null;
                    }

                    return;
                }

                socket = m_socket;
            }

            BufferManager.LockBuffer(m_receiveBuffer);

            try {
                socket.BeginReceive(
                    m_receiveBuffer,
                    m_bytesReceived,
                    m_bytesToReceive - m_bytesReceived,
                    SocketFlags.None,
                    m_ReadComplete,
                    null);
            } catch (Exception e) {
                BufferManager.UnlockBuffer(m_receiveBuffer);
                throw ServiceResultException.Create(StatusCodes.BadTcpInternalError, e, "BeginReceive failed.");
            }
        }
        /// <summary>
        /// Reads the next block of data from the socket.
        /// </summary>
        private void ReadNextBlock()
        {
            Socket socket = null;

            // check if already closed.
            lock (m_socketLock)
            {
                if (m_socket == null)
                {
                    if (m_receiveBuffer != null)
                    {
                        m_bufferManager.ReturnBuffer(m_receiveBuffer, "ReadNextBlock");
                        m_receiveBuffer = null;
                    }

                    return;
                }

                socket = m_socket;

                // avoid stale ServiceException when socket is disconnected
                if (!socket.Connected)
                {
                    return;
                }
            }

            BufferManager.LockBuffer(m_receiveBuffer);

            ServiceResult        error = ServiceResult.Good;
            SocketAsyncEventArgs args  = new SocketAsyncEventArgs();

            try
            {
                args.SetBuffer(m_receiveBuffer, m_bytesReceived, m_bytesToReceive - m_bytesReceived);
                args.Completed += m_ReadComplete;
                if (!socket.ReceiveAsync(args))
                {
                    // I/O completed synchronously
                    if ((args.SocketError != SocketError.Success) || (args.BytesTransferred < (m_bytesToReceive - m_bytesReceived)))
                    {
                        throw ServiceResultException.Create(StatusCodes.BadTcpInternalError, args.SocketError.ToString());
                    }

                    args.Dispose();
                }
            }
            catch (ServiceResultException sre)
            {
                args.Dispose();
                BufferManager.UnlockBuffer(m_receiveBuffer);
                throw sre;
            }
            catch (Exception ex)
            {
                args.Dispose();
                BufferManager.UnlockBuffer(m_receiveBuffer);
                throw ServiceResultException.Create(StatusCodes.BadTcpInternalError, ex, "BeginReceive failed.");
            }
        }
Пример #3
0
        /// <summary>
        /// Reads the next block of data from the socket.
        /// </summary>
        private void ReadNextBlock()
        {
            Socket socket = null;

            // check if already closed.
            lock (m_socketLock)
            {
                if (m_socket == null)
                {
                    if (m_receiveBuffer != null)
                    {
                        m_bufferManager.ReturnBuffer(m_receiveBuffer, "ReadNextBlock");
                        m_receiveBuffer = null;
                    }
                    m_readState = ReadState.NotConnected;
                    return;
                }

                socket = m_socket;

                // avoid stale ServiceException when socket is disconnected
                if (!socket.Connected)
                {
                    m_readState = ReadState.NotConnected;
                    return;
                }
            }

            BufferManager.LockBuffer(m_receiveBuffer);

            var args = new SocketAsyncEventArgs();

            try
            {
                m_readState = ReadState.Receive;
                args.SetBuffer(m_receiveBuffer, m_bytesReceived, m_bytesToReceive - m_bytesReceived);
                args.Completed += m_readComplete;
                if (!socket.ReceiveAsync(args))
                {
                    // I/O completed synchronously
                    if (args.SocketError != SocketError.Success)
                    {
                        throw ServiceResultException.Create(StatusCodes.BadTcpInternalError, args.SocketError.ToString());
                    }
                    // set state to inner complete
                    m_readState = ReadState.ReadComplete;
                    m_readComplete(null, args);
                }
            }
            catch (ServiceResultException)
            {
                args?.Dispose();
                BufferManager.UnlockBuffer(m_receiveBuffer);
                throw;
            }
            catch (Exception ex)
            {
                args?.Dispose();
                BufferManager.UnlockBuffer(m_receiveBuffer);
                throw ServiceResultException.Create(StatusCodes.BadTcpInternalError, ex, "BeginReceive failed.");
            }
        }
Пример #4
0
        /// <summary>
        /// Handles a read complete event.
        /// </summary>
        private ServiceResult DoReadComplete(IAsyncResult result)
        {
            // complete operation.
            int bytesRead = 0;

            lock (m_socketLock) {
                try {
                    if (m_socket != null)
                    {
                        bytesRead = m_socket.EndReceive(result);
                        // Utils.Trace("EndReceive {0} bytes", bytesRead);
                    }

#if TRACK_MEMORY
                    int cookie = BitConverter.ToInt32(m_receiveBuffer, 0);

                    if (cookie < 0)
                    {
                        Utils.Trace("BufferCookieError (EndReceive): Cookie={0:X8}", cookie);
                    }
#endif
                } finally {
                    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;
                }

                // put a null buffer to ensure that all queued messages are processed before close.
                lock (m_readQueue) {
                    m_readQueue.AddLast(new ArraySegment <byte>());

                    if (m_readQueue.Count == 1 && !m_readThreadActive)
                    {
                        ThreadPool.QueueUserWorkItem(ReadQueuedMessages, 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();

#if TRACK_MEMORY
                int cookie = BitConverter.ToInt32(m_receiveBuffer, 0);

                if (cookie < 0)
                {
                    Utils.Trace("BufferCookieError (ReadNextBlock): Cookie={0:X8}", cookie);
                }
#endif

                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);
            }

            // add message to queue.
            ArraySegment <byte> messageChunk = new ArraySegment <byte>(m_receiveBuffer, 0, m_incomingMessageSize);

            // must allocate a new buffer for the next message.
            m_receiveBuffer = null;

            lock (m_readQueue) {
#if TRACK_MEMORY
                int cookie = BitConverter.ToInt32(messageChunk.Array, 0);

                if (cookie < 0)
                {
                    Utils.Trace("BufferCookieError (DoReadComplete): Cookie={0:X8}", cookie);
                }
#endif

                BufferManager.LockBuffer(messageChunk.Array);
                m_readQueue.AddLast(messageChunk);

                if (m_readQueue.Count == 1 && !m_readThreadActive)
                {
                    ThreadPool.QueueUserWorkItem(ReadQueuedMessages, null);
                }
            }

            // start receiving next message.
            ReadNextMessage();
            return(ServiceResult.Good);
        }