public bool Connect()
        {
            try
            {
                StateObject state = new StateObject();

                if (stackContext.peers[0].PeerConnection == null || !(stackContext.peers[0].PeerConnection.Connected))
                {
                    StackLog.Write2TraceLog("\r\n\nTransport.SendMessage()", "Establishing the Connection");

                    Common.StackLog.Write2TraceLog("Transport::SendMessage", "Connecting remote Peer[ " + stackContext.peers[0].PeerIPAddress + ":" + stackContext.peers[0].PeerPort + "]");

                    stackContext.peers[0].PeerConnection = new TcpClient(stackContext.peers[0].PeerIPAddress, stackContext.peers[0].PeerPort);

                    stackContext.peers[0].PeerConnection.ReceiveBufferSize = MAX_TCP_BUFF_SIZE;

                    Common.StackLog.Write2TraceLog("Transport::SendMessage() ", " Connection Established..");

                    //Update Peer Connection State
                    DiameterAAAStack.UpdateConnectionState(stackContext.peers[0], PeerState.OPEN);

                    Common.StackLog.Write2TraceLog("Transport::SendMessage() ", " Connection State Changed to OPEN..");

                    //Start Data Processing Thread
                    //pProcessDataThread = new Thread(processData);
                    //pProcessDataThread.Start();
                    //Start Receive CallBack

                    tcpClient = stackContext.peers[0].PeerConnection;

                    tcpClient.Client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
                    state.workSocket = tcpClient.Client;
                }
            }
            catch (Exception e)
            {
                Common.StackLog.Write2ErrorLog("Connect", "Error Connecting:" + e.Message + " Stack:" + e.StackTrace);
                return(false);
            }
            return(true);
        }
        /// <summary>
        /// Send Message to the Diameter Peer
        /// </summary>
        /// <param name="MessageBytes"></param>
        /// <param name="TransportType"></param>
        /// <param name="remotePeer"></param>
        public Message SendMessage(Message diameterRequest, Peer destPeer)
        {
            try
            {
                byte[] mgsBytesToSend = diameterRequest.GetBytes();

                //Connect if not connected
                if (stackContext.peers[0].PeerConnection == null || !stackContext.peers[0].PeerConnection.Connected)
                {
                    if (diameterRequest.CommandCode != DiameterMessageCode.CAPABILITY_EXCHANGE)
                    {
                        Common.StackLog.Write2ErrorLog("Transport::SendMessage", "Connection Broken, calling Connect()");
                    }

                    //Connect Diameter Socket
                    Connect();
                }


                Thread pWaiterThread;

                //Just Copy to localThreadWaiter Variable.
                pWaiterThread = Thread.CurrentThread;

                //CCRWaiter vRespWaiter = null;
                //if Message is a CCR message, we need to wait for a response, so add Session to CCRSession
                if (diameterRequest.CommandCode == DiameterMessageCode.CREDIT_CONTROL)
                {
                    ResponseWaiter.AddRequest(diameterRequest.SessionID, pWaiterThread);
                }
                //CER Never Contains a Session ID
                else if (diameterRequest.CommandCode == DiameterMessageCode.CAPABILITY_EXCHANGE)
                {
                    ResponseWaiter.AddRequest("CEX", pWaiterThread);
                    diameterRequest.SessionID = "CEX";
                }
                else
                {
                    StackLog.Write2TraceLog("Transport.SendMessage() ", "UnHandled Message Type:" + diameterRequest.CommandCode);
                    return(null);
                }
                //Record Time
                TimeSpan STime = new TimeSpan(DateTime.Now.Ticks);
                ///////////////////////////////Send Message to the Remote Peer ////////////////////////////////

                //StackLog.Write2TraceLog("\r\nSendMessage", diameterRequest.ToString());
                msgLogger.Write2MessageLog(diameterRequest.ToString());

                Common.StackLog.Write2TraceLog("Transport::SendMessage() ", " Sending Message " + DiameterMessageCode.GetMessageName(diameterRequest.CommandCode, true) + " (" + diameterRequest.SessionID + ") ..");

                destPeer.PeerConnection.GetStream().Write(mgsBytesToSend, 0, mgsBytesToSend.Length);

                //Wait for Response;
                Common.StackLog.Write2TraceLog("Transport::SendMessage() ", " Message Sent, Waiting For Diameter Message Response of Session: " + diameterRequest.SessionID);
                bool isInterrupted = false;
                try
                {
                    //Sleep for 3 Seconds Maximum until interrupted.
                    for (int i = 0; i <= stackContext.CCATimeout * 10; i++)
                    {
                        Thread.Sleep(100);
                    }
                }
                catch (ThreadInterruptedException ex)
                {
                    isInterrupted = true;
                    //StackLog.Write2ErrorLog("SendMessage", "Thread Intrupted for for Response for the Session: " + diameterRequest.SessionID);
                }

                if (isInterrupted)
                {
                    Common.StackLog.Write2TraceLog("Transport.SendMessage() ", " Waiter Thread Response Interrupted for Session: " + diameterRequest.SessionID);
                }
                else
                {
                    Common.StackLog.Write2TraceLog("Transport.SendMessage() ", " Waiter Thread Response Timedout for Session: " + diameterRequest.SessionID);
                }

                //After Thread intrruption get the response here.
                //CEX Dont have any session ID so validate here.
                Message diameterResponse;
                if (ResponseWaiter.ContainsResponse(diameterRequest.SessionID))
                {
                    diameterResponse = ResponseWaiter.GetResponse(diameterRequest.SessionID);
                }
                else
                {
                    Common.StackLog.Write2ErrorLog("Transport::SendMessage", "Response message not available for " + DiameterMessageCode.GetMessageName(diameterRequest.CommandCode, true) + " " + diameterRequest.SessionID);
                    return(null);
                }
                //Check the Recieved Response
                if (diameterResponse != null)
                {
                    Common.StackLog.Write2TraceLog("Transport.SendMessage() ", "Response Message " + DiameterMessageCode.GetMessageName(diameterResponse.CommandCode, false) + " of Request Session: " + diameterRequest.SessionID + " with Response of:" + diameterResponse.SessionID.ToString() + " Received..\r\n");

                    /*if (diameterResponse.avps.Count == 0)
                     * {
                     *  StackLog.Write2ErrorLog("SendMessage", "Response Msg has no AVP's for Session:" + diameterResponse.SessionID);
                     *  StackLog.Write2ErrorLog("SendMessage", diameterResponse.ToString());
                     * }*/
                    ////Log Recieved Message
                    //StackLog.Write2MessageLog(diameterResponse.ToString());
                    msgLogger.Write2MessageLog(diameterResponse.ToString());
                    TimeSpan ETime = new TimeSpan(DateTime.Now.Ticks);
                    diameterResponse.ExecTime = ETime.Subtract(STime).Milliseconds;
                    //diameterResponse.PrintMessage();
                }
                else
                {
                    Common.StackLog.Write2ErrorLog("Transport::SendMessage", "Unable to Receive Response message for " + DiameterMessageCode.GetMessageName(diameterRequest.CommandCode, true) + " " + diameterRequest.SessionID);
                    //Common.StackLog.Write2ErrorLog("Transport::SendMessage", diameterRequest.ToString());
                }

                return(diameterResponse);
            }
            catch (Exception exp)
            {
                StackLog.Write2ErrorLog("DiameterTransport:SendMessage()", "Error:" + exp.Message + " Stack:" + exp.StackTrace.ToString());
                //throw exp;
                return(null);
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="listenAddresses"></param>
        public void StartListners(List <ListenAddress> listenAddresses, ref TcpListener listner)
        {
            byte[] responseBuffer = new byte[4000];

            try
            {
                SocketAddress address = new SocketAddress(System.Net.Sockets.AddressFamily.InterNetwork);

                foreach (ListenAddress socketAddr in listenAddresses)
                {
                    Common.StackLog.Write2TraceLog("Transport::SendMessage", "Starting Listening on " + socketAddr.IPAddress.ToString() + " with Port: " + socketAddr.Port.ToString());

                    listner = new TcpListener(IPAddress.Parse(socketAddr.IPAddress), socketAddr.Port);

                    listner.Start();

                    Common.StackLog.Write2TraceLog("Transport::SendMessage", "Started Listening on " + listner.LocalEndpoint.ToString());

                    StackLog.Write2TraceLog("StartListners", "Started Listening on " + socketAddr.IPAddress + ":" + socketAddr.Port.ToString());
                }

                while (true)
                {
                    //try
                    //{
                    if (listner.Pending())
                    {
                        Common.StackLog.Write2TraceLog("Transport::StartListener", "Listening for Peer Connections ");

                        Socket socket = listner.AcceptSocket();

                        Common.StackLog.Write2TraceLog("Transport::StartListener", "Recieved Message From [" + socket + " ]");

                        //Get the Message Length
                        Array.Clear(responseBuffer, 0, responseBuffer.Length);

                        int rcvdcount = socket.Receive(responseBuffer);

                        byte[] RcvdBytes = new byte[rcvdcount];

                        Buffer.BlockCopy(responseBuffer, 0, RcvdBytes, 0, rcvdcount);
                        //
                        IPEndPoint remotePeer = socket.RemoteEndPoint as IPEndPoint;

                        RecievedMessageInfo rcvdObject = new RecievedMessageInfo()
                        {
                            data = RcvdBytes, PeerIdentity = new URI("aaa://" + remotePeer.Address + ":" + remotePeer.Port + ";transport=tcp;protocol=diameter")
                        };

                        DiameterAAAStack.RaisePeerStateChangeEvent(PEER_STATE_EVENT.Rcv_Message, RcvdBytes);

                        Array.Clear(responseBuffer, 0, responseBuffer.Length);
                    }
                    //}
                    //catch (Exception ex)
                    //{
                    //}
                }
            }
            catch (Exception exp)
            {
                //Write Log Here..
                Common.StackLog.Write2ErrorLog("Transport::StartListners()", "Error:" + exp.Message + " Stack:" + exp.StackTrace);
                //Shutdown and end connection

                //listner.Stop();

                //throw exp;
            }
            finally
            {
                listner.Stop();
            }
        }