Пример #1
0
        /// <summary>
        /// Handles incoming network traffic on this (Master,Agent) connection.
        /// Initially keeps going until we have a complete message header. When it has a complete
        /// header it determines the message length and keeps going until it has the entire message.
        /// Once it has a complete message it calls passes it to the Rate Controller for parsing.
        /// </summary>
        /// <param name="ar"></param>
        public void receiveComplete(IAsyncResult ar)
        {
            int bytesIn = 0;
            int offset  = 0;

            try
            {
                lock (LockReceive)
                {
                    Debug.Assert(Interlocked.Decrement(ref DbgBeginReceivePending) == 0);
                    CallbackContext callbackContext = (CallbackContext)ar.AsyncState;
                    Socket          socket          = callbackContext.socket;
                    bytesIn       = socket.EndReceive(ar);
                    offset        = callbackContext.offset;
                    bytesReceived = offset + bytesIn;
                    currOffset   += bytesIn;
                    if (bytesReceived == 0)
                    {
                        callbacks.ReceiveClose(this);
                    }
                    else if (bytesReceived < Message.SIZEOF_MESSAGE_HEADER)
                    {
                        // At outset must get enough bytes to extract message size from header.
                        int bytesNeeded = Message.SIZEOF_MESSAGE_HEADER - bytesReceived;
                        BeginReceive(receiveBuffer, currOffset, bytesExpected, receiveComplete);
                    }
                    else if (bytesReceived == Message.SIZEOF_MESSAGE_HEADER)
                    {
                        // We now have a complete message header and can determine message size.
                        messageHeader.InitFromNetBytes(receiveBuffer, 0);
                        int msgLen = messageHeader.GetLength();
                        bytesExpected += msgLen;
                        if (msgLen == 0 || bytesReceived == bytesExpected)
                        {
                            // The message has a zero-length body.
                            callbacks.ReceiveMessage(this, messageHeader.GetMessageType(), receiveBuffer, 0, bytesReceived);
                        }
                        else if (bytesReceived < bytesExpected)
                        {
                            int bytesNeeded = bytesExpected - bytesReceived;
                            BeginReceive(receiveBuffer, bytesReceived, bytesNeeded, receiveComplete);
                        }
                        else
                        {
                            // Should never get here.
                            throw new ApplicationException("Conn: received too many bytes (a).");
                        }
                    }
                    else if (bytesReceived < bytesExpected)
                    {
                        // Received an incomplete message and must obtain the missing (trailing) bytes.
                        int bytesNeeded = bytesExpected - bytesReceived;
                        BeginReceive(receiveBuffer, bytesReceived, bytesNeeded, receiveComplete);
                    }
                    else if (bytesReceived == bytesExpected)
                    {
                        // We have a complete message. Hand it to the Rate Controller for parsing.
                        callbacks.ReceiveMessage(this, messageHeader.GetMessageType(), receiveBuffer, 0, bytesReceived);
                    }
                    else
                    {
                        // Should never get here.
                        throw new ApplicationException("Conn: received too many bytes (b).");
                    }
                }
            }
            catch (SocketException sockEx)
            {
                callbacks.CatchSocketException(this, sockEx);
            }
            catch (ObjectDisposedException odex)
            {
                Console.WriteLine("receiveComplete caught ObjectDisposedException {0}", odex.Message);
            }
        }