/// <summary>
        /// Wait for a connection or disconnection from client
        /// </summary>
        /// <param name="timeout">Max time for waiting</param>
        /// <param name="kileConnection">Maintain a connection with a target client</param>
        /// <exception cref="System.InvalidOperationException">
        /// Thrown when the transport event is neither connected nor disconnected.</exception>
        public void ExpectConnection(TimeSpan timeout, out KileConnection kileConnection)
        {
            TransportEvent transEvent = transport.ExpectTransportEvent(timeout);

            if (transEvent.EventType != EventType.Connected && transEvent.EventType != EventType.Disconnected)
            {
                throw new InvalidOperationException("Received an unexpected transport event");
            }
            IPEndPoint ipEndPoint = (IPEndPoint)transEvent.EndPoint;

            kileConnection = new KileConnection(ipEndPoint);
        }
        /// <summary>
        /// Expect to receive a PDU of any type from the remote host.
        /// </summary>
        /// <param name="timeout">Timeout of receiving PDU.</param>
        /// <returns>The expected PDU.</returns>
        /// <exception cref="System.TimeoutException">Thrown when the timeout parameter is negative.</exception>
        public KerberosPdu ExpectPdu(TimeSpan timeout, Type pduType = null)
        {
            this.expectedPduType = pduType;
            KerberosPdu pdu = null;

            if (UseProxy)
            {
                Debug.Assert(ProxyClient != null, "Proxy Client should be set when using proxy.");
                int consumedLength = 0;
                int expectedLength = 0;
                if (ProxyClient.Error == KKDCPError.STATUS_SUCCESS)
                {
                    KDCProxyMessage message = ProxyClient.GetProxyResponse();
                    //temporarily change the tranpsort type to TCP, since all proxy messages are TCP format.
                    var oriTransportType = Context.TransportType;
                    Context.TransportType = TransportType.TCP;
                    //get proxy message
                    pdu = getExpectedPduFromBytes(message.Message.kerb_message.ByteArrayValue, out consumedLength, out expectedLength);
                    //restore the original transport type
                    Context.TransportType = oriTransportType;
                }
            }
            else
            {
                if (timeout.TotalMilliseconds < 0)
                {
                    throw new TimeoutException(KerberosConstValue.TIMEOUT_EXCEPTION);
                }
                TransportEvent eventPacket = kdcTransport.ExpectTransportEvent(timeout);
                pdu = (KerberosPdu)eventPacket.EventObject;
                this.DisConnect();
            }
            return(pdu);
        }
        /// <summary>
        /// Expect to receive a PDU of any type from the remote host.
        /// </summary>
        /// <param name="timeout">Timeout of receiving PDU.</param>
        /// <returns>The expected PDU.</returns>
        /// <exception cref="System.TimeoutException">Thrown when the timeout parameter is negative.</exception>
        public KilePdu ExpectPdu(TimeSpan timeout)
        {
            if (timeout.TotalMilliseconds < 0)
            {
                throw new TimeoutException(ConstValue.TIMEOUT_EXCEPTION);
            }

            TransportEvent eventPacket = kdcTransport.ExpectTransportEvent(timeout);
            KilePdu        packet      = (KilePdu)eventPacket.EventObject;

            return(packet);
        }