/// <summary>
        /// receive date stream through socket
        /// </summary>
        /// <param name="control"></param>
        private void __threadListen(ThreadControl control)
        {
            logger.Debug($"{nameof(__threadListen)}() on duty.");

            var  count = 1;                         // the actual received count of bytes by socket
            var  lenBuff = new byte[sizeof(uint)];  // store the message length number in byte format
            var  slot = new byte[slotSize];         // reception slot, it could maintain the integral data of a message
            int  k = 0, l = 0;                      // pointer for slot, pointer for lenBuff
            uint msgLen = 0, verifyLen = 0;         // message header, check code
            var  rbuffer    = new byte[bufferSize]; // reception buffer
            var  slotBackup = slot;                 // switch back to the primal slot after using super slot

            socket.SendBufferSize = this.bufferSize;

            while (!control.SafelyTerminating)
            {
                /*******************************
                * receive bytes through socket
                * *****************************/
                rwlsSocket.EnterReadLock();
                try
                {
                    var result = socket.BeginReceive(rbuffer, 0, rbuffer.Length, SocketFlags.None, x => x = null, null); // async reception,to realize 'SafelyTermination'
                    while (!control.SafelyTerminating && !result.IsCompleted)                                            // wait for completion
                    {
                        Thread.Sleep(1);
                    }
                    if (control.SafelyTerminating || !socket.Connected)
                    {
                        break;                                                  // termination signal detected, stop listening
                    }
                    count = socket.EndReceive(result);
                }
                catch (SocketException se)
                {
                    logger.Error($"{se.Message}");
                    break;
                }
                catch (Exception ex)
                {
                    logger.Fatal("fatal error occurred in __threadListen.", ex);
                    Catch(new EOCException(ex));
                    break;
                }
                finally
                {
                    rwlsSocket.ExitReadLock();
                }

                /*****************************
                * process the received bytes
                * ***************************/
                for (var j = 0; j < count;)  // deal with the bytes received in rbuffer
                {
                    if (msgLen == 0)
                    {
                        lenBuff[l] = rbuffer[j];
                        ++j;  // point to the 1st byte of content
                        if (++l == lenBuff.Length)
                        {
                            l      = 0;
                            msgLen = BitConverter.ToUInt32(lenBuff, 0);
                            if (verifyLen != 0)                       // need validation
                            {
                                if (verifyLen == msgLen)              // validatin OK
                                {
                                    watchDog = 0;                     // feed local dog, reset the timer
                                    if (msgLen == 1)                  // system command code
                                    {
                                        if (slot[0] == DOG_FOOD_FLAG) // dog food
                                        {
                                            // pass
                                        }
                                    }
                                    else
                                    {
                                        var msg = EMessage.FromBytes(slot, 0, k);
                                        ThreadPool.QueueUserWorkItem(_processInMessage, msg);
                                    }
                                    msgLen = 0;
                                }
                                else
                                {
                                    Catch(new EOCException("transmission error, please reconnect!"));
                                }
                                verifyLen = 0;
                                if (slot.Length != slotSize)
                                {
                                    slot = slotBackup;
                                }
                            }
                            else
                            {
                                if (msgLen > slotSize)
                                {
                                    slot = new byte[msgLen];  // super slot
                                }
                            }
                            k = 0;
                        }
                    }
                    else
                    {
                        int n = (int)(msgLen - k);
                        if (n + j > count)
                        {
                            n = count - j;
                        }
                        Array.Copy(rbuffer, j, slot, k, n);
                        k += n;
                        j += n;
                        if (k == msgLen)
                        {
                            verifyLen = msgLen;
                            msgLen    = 0;
                        }
                    }
                }
            }

            control.SetAbortedFlags();

            OnThreadListenAborted();

            logger.Debug($"{nameof(__threadListen)}() aborted.");
        }
        /// <summary>
        /// watch dog has the highest authority in agent, it performs some light weight operations, such as update 'TCounters'
        /// </summary>
        private void __threadWatchdog(ThreadControl control)
        {
            logger.Debug($"{nameof(__threadWatchdog)}() on duty.");

            var feedCycle      = Math.Min(1000, this.timeout >> 1); // the cycle of dog feeding, unit: ms
            var feedTCounter   = 0;
            var msg            = new EMessage(0);
            var foodBag        = new[] { DOG_FOOD_FLAG };
            var threadInterval = 1;  // watch dog scan cycle, ms

            while (!control.SafelyTerminating)
            {
                Thread.Sleep(threadInterval);

                // -1 denote that the dog is dead,only __threadListen can set it back to '0' to rebirth the dog
                if (watchDog == -1)
                {
                    continue;                  // no more actions when dog has died
                }

                /*******************
                * update TCounters
                * *****************/
                KeyValuePair <uint, TCounter>[] msgIdAndTCounterPairs;
                lock (dictMsgId2TC) msgIdAndTCounterPairs = dictMsgId2TC.ToArray();
                foreach (var kv in msgIdAndTCounterPairs)
                {
                    if (kv.Value.Decrease(threadInterval) || !this.IsConnected) // request timeout
                    {
                        kv.Value.CountDown = 0;                                 // set countdown to 'timeout'
                        RemoveWaitFlag(kv.Key);
                        ThreadPool.QueueUserWorkItem(_processTimeoutMessage, kv.Value.RequestMsg);
                    }
                }

                /************
                * watch dog
                * **********/
                if (IsConnected)
                {
                    // check local dog
                    watchDog += threadInterval;
                    if (watchDog >= timeout)
                    {
                        watchDog = -1;  // time out flag

                        GetControl(ThreadType.Listen).SafeAbort();
                        OnConnectionTimeout();
                        logger.Error($"{this} connection timeout.");
                    }

                    // feed remote dog
                    feedTCounter += threadInterval;
                    if (feedTCounter >= feedCycle)
                    {
                        feedTCounter = 0;  // reset

                        try
                        {
                            SendBytes(foodBag, 0, foodBag.Length);
                        }
                        catch
                        {
                            // pass, ignore all errors
                        }
                    }
                }
            }

            control.SetAbortedFlags();

            logger.Debug($"{nameof(__threadWatchdog)}() aborted.");

            this.Destroy();
            this.Phase = ConnectionPhase.P0Start;
        }