Exemplo n.º 1
0
        /// <summary>
        /// Called when the channel is open after the call to select().
        /// </summary>
        public void AfterSelectOpen(SelectSockets selectSockets)
        {
            // Perform transfers only if the socket is ready.
            if (!selectSockets.InReadOrWrite(Sock)) return;

            // Build the received message list.
            List<AnpMsg> recvList = new List<AnpMsg>();

            while (true)
            {
                // Prepare a transfer.
                PrepareNextMsgTransfer();

                // Remember if we are sending a message.
                bool sendingFlag = Transport.IsSending;

                // Do transfers.
                Transport.DoXfer();

                // Stop if no message has been received and no message has been sent.
                if (!Transport.DoneReceiving && (!sendingFlag || Transport.IsSending)) break;

                // Add the message received.
                if (Transport.DoneReceiving) recvList.Add(Transport.GetRecv());
            }

            // Dispatch the received messages.
            if (recvList.Count > 0) Worker.NotifyMsgReceived(ChannelID, recvList);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Analyse the result of the select() call for the specified KCD.
        /// </summary>
        private void UpdateStateAfterSelect(KcdThreadHost k, SelectSockets selectSockets)
        {
            try
            {
                k.CheckNoMessageReceivedInvariant();

                // We have nothing to do if we don't have an established TCP
                // connection.
                if (k.ConnStatus != KcdThreadConnStatus.Connected &&
                    k.ConnStatus != KcdThreadConnStatus.RoleReply) return;

                // Perform transfers only if the socket is ready.
                Debug.Assert(k.Tunnel.Sock != null);
                if (!selectSockets.InReadOrWrite(k.Tunnel.Sock)) return;

                // Do up to 20 transfers (the limit exists for quenching purposes).
                for (int i = 0; i < 20; i++)
                {
                    // Send a message if possible.
                    k.SendNextQueuedMsgIfNeeded();

                    // Remember if we are sending a message.
                    bool sendingFlag = k.Tunnel.IsSendingMessage();

                    // Do transfers.
                    k.Tunnel.DoXfer();

                    // Stop if no message has been received and no message has been sent.
                    if (!k.Tunnel.HasReceivedMessage() &&
                        (!sendingFlag || k.Tunnel.IsSendingMessage())) break;

                    // Process the message received.
                    if (k.Tunnel.HasReceivedMessage()) ProcessIncomingKcdMessage(k, k.Tunnel.GetMsg());
                }

                k.CheckNoMessageReceivedInvariant();
            }

            catch (Exception ex)
            {
                HandleDisconnectedKcd(k, ex);
            }
        }