/*
         * AsynchronousReader (constructor)
         * Does the following :
         * 1. Copy the state object which contains all the data needed for reading to member variable
         * 2. Create and activate the reading thread
         */

        /**********************************************************************************************//**
        * Constructor.
        *
        * \author  Ilan Hindy
        * \date    29/09/2016
        *
        * \param   listenState State of the listen.
        *
        **************************************************************************************************/

        public AsynchronousReader(SocketStateObject listenState)
        {
            this.state = new SocketStateObject(listenState);
            string sourcePort = ((IPEndPoint)state.workSocket.RemoteEndPoint).Port.ToString();

            ReadThread      = new Thread(ReadLoop);
            ReadThread.Name = listenState.process.ea[bp.eak.Name] + " Read port " + sourcePort;
            ReadThread.Start();
        }
        /*
         * Start sending - the main method of the sending
         */

        /**********************************************************************************************//**
        * Starts a sending.
        *
        * \author  Ilan Hindy
        * \date    29/09/2016
        *
        * \param   message The message.
        * \param   process The process.
        * \param   channel The channel.
        *
        **************************************************************************************************/

        public static void StartSending(BaseMessage message, BaseProcess process, BaseChannel channel)
        {
            try
            {
                // Establish the remote endpoint for the socket.
                string     localAddress = Dns.GetHostEntry(Dns.GetHostName()).AddressList.First(f => f.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).ToString();
                IPEndPoint remoteEP     = new IPEndPoint(IPAddress.Parse(localAddress), channel.or[bc.ork.DestPort]);

                // Build the state object
                SocketStateObject state = new SocketStateObject();
                state.process = process;

                Socket client;

                //If this is the first time that there is a sending through the channel
                if (channel.sendingSocket == null)
                {
                    //Establish the local end point for the socket
                    int        localPort     = channel.or[bc.ork.SourcePort];
                    IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse(localAddress), localPort);

                    //Create a new socket
                    client = new Socket(AddressFamily.InterNetwork,
                                        SocketType.Stream, ProtocolType.Tcp);

                    //Bind the local address
                    client.Bind(localEndPoint);

                    //Set the socket in the channel and in the state object
                    channel.sendingSocket = client;
                    state.clientSocket    = client;


                    // Connect to the remote endpoint.
                    Logger.Log(Logger.LogMode.MainLogAndProcessLogAndMessageTrace, process.GetProcessDefaultName(), "AsynchronousSender.StartSending()", "before BeginConnect()", "", "ProcessSend");
                    client.BeginConnect(remoteEP,
                                        new AsyncCallback(ConnectCallback), state);
                    state.connectDone.WaitOne();
                }
                else //This is not the first sending from the channel
                {
                    //Get the socket from the channel and set it in the state object
                    client             = channel.sendingSocket;
                    state.clientSocket = client;
                }

                // Send test data to the remote device.
                MessageRouter.ReportMessageSent(process, new object[] { message });
                Send(message, state);
                state.sendDone.WaitOne();
            }
            catch (Exception e)
            {
                Logger.Log(Logger.LogMode.MainLogProcessLogAndError, process.GetProcessDefaultName(), "AsynchronousSender.StartSending()", "Error", e.ToString(), "Error");
            }
        }
예제 #3
0
        /*
         * StartListening
         * This method listen to new connections n an infinit loop
         * The loop terminates when the StopFlag of the process is set to true
         * There is one listener for each process
         */

        /**********************************************************************************************//**
        * Starts a listening.
        *
        * \author  Ilan Hindy
        * \date    29/09/2016
        *
        * \param   localPort   The local port.
        * \param   process     The process.
        *
        **************************************************************************************************/

        public static void StartListening(int localPort, BaseProcess process)
        {
            // Establish the local endpoint for the socket.
            string     localAddress  = Dns.GetHostEntry(Dns.GetHostName()).AddressList.First(f => f.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).ToString();
            IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse(localAddress), localPort);

            // Create a TCP/IP socket.
            Socket listener = new Socket(AddressFamily.InterNetwork,
                                         SocketType.Stream, ProtocolType.Tcp);

            try
            {
                // Bind the socket to the local endpoint and listen for incoming connections.
                listener.Bind(localEndPoint);
                listener.Listen(100);

                while (true)
                {
                    // Create state
                    SocketStateObject state = new SocketStateObject();
                    state.process      = process;
                    state.listenSocket = listener;

                    // Set the event to nonsignaled state.
                    state.allDone.Reset();

                    // Start an asynchronous socket to listen for connections.
                    listener.BeginAccept(
                        new AsyncCallback(AcceptCallback),
                        state);

                    //Wait untill the connection is done
                    state.allDone.WaitOne();

                    // Check if the process ended it's algorithm
                    Logger.Log(Logger.LogMode.MainLogAndProcessLog, process.GetProcessDefaultName(), "AsynchronousSocketListener.StartListening()", "StopFlag = " + process.StopFlag.ToString(), "", "ProcessReceive");
                    if (process.StopFlag == true)
                    {
                        Thread.Sleep(100);
                        Logger.Log(Logger.LogMode.MainLogAndProcessLog, process.GetProcessDefaultName(), "AsynchronousSocketListener.StartListening()", "listen thread terminated StopFlag = " + process.StopFlag.ToString(), "", "ProcessReceive");

                        return;
                    }
                }
            }
            catch (Exception e)
            {
                Logger.Log(Logger.LogMode.MainLogProcessLogAndError, process.GetProcessDefaultName(), "AsynchronousSocketListener.StartListening()", e.ToString(), "", "Error");
            }
        }
예제 #4
0
        /**********************************************************************************************//**
        * Constructor.
        *
        * \author  Ilan Hindy
        * \date    29/09/2016
        *
        * \param   state   The state.
        *
        **************************************************************************************************/

        public SocketStateObject(SocketStateObject state)
        {
            workSocket   = state.workSocket;
            listenSocket = state.listenSocket;
            process      = state.process;
            clientSocket = state.clientSocket;
            connectDone  = state.connectDone;
            sendDone     = state.sendDone;
            allDone      = state.allDone;
            sb           = new StringBuilder();
            buffer       = new byte[BufferSize];
            connectDone  = new ManualResetEvent(false);
            sendDone     = new ManualResetEvent(false);
            allDone      = new ManualResetEvent(false);
        }
        /*
         * SendCallback
         * This function is called by the socket when it ended the sending
         */

        /**********************************************************************************************//**
        * Sends a callback.
        *
        * \author  Ilan Hindy
        * \date    29/09/2016
        *
        * \param   ar  The archive.
        *
        **************************************************************************************************/

        private static void SendCallback(IAsyncResult ar)
        {
            // Retrieve the socket from the state object.
            SocketStateObject state   = (SocketStateObject)ar.AsyncState;
            Socket            client  = state.clientSocket;
            BaseProcess       process = state.process;

            try
            {
                // Complete sending the data to the remote device.
                int bytesSent = client.EndSend(ar);

                // Signal that all bytes have been sent.
                state.sendDone.Set();
            }
            catch (Exception e)
            {
                Logger.Log(Logger.LogMode.MainLogProcessLogAndError, process.GetProcessDefaultName(), "AsynchronousSender.SendCallback()", e.ToString(), "Error");
            }
        }
        /*
         * ConnectCallback
         * This function is called by the socket when it ended the connection
         */

        /**********************************************************************************************//**
        * Connects a callback.
        *
        * \author  Ilan Hindy
        * \date    29/09/2016
        *
        * \param   ar  The archive.
        *
        **************************************************************************************************/

        private static void ConnectCallback(IAsyncResult ar)
        {
            // Retrieve the socket from the state object.
            SocketStateObject state   = (SocketStateObject)ar.AsyncState;
            Socket            client  = state.clientSocket;
            BaseProcess       process = state.process;

            try
            {
                // Complete the connection.
                client.EndConnect(ar);

                // Signal that the connection has been made.
                state.connectDone.Set();
            }
            catch (Exception e)
            {
                Logger.Log(Logger.LogMode.MainLogProcessLogAndError, process.GetProcessDefaultName(), "AsynchronousSender.ConnectCallback()", e.ToString(), "Error");
            }
        }
        /*
         * Send
         * This function sends one packet
         */

        /**********************************************************************************************//**
        * Send this message.
        *
        * \author  Ilan Hindy
        * \date    29/09/2016
        *
        * \param   message The message.
        * \param   state   The state.
        *
        **************************************************************************************************/

        private static void Send(BaseMessage message, SocketStateObject state)
        {
            // Retrieve the socket from the state object.
            Socket client = state.clientSocket;

            try
            {
                //Logging the send message
                Logger.Log(Logger.LogMode.MainLogAndProcessLogAndMessageTrace, state.process.GetProcessDefaultName(), "AsynchronousSender.Send()", "SEND", message, "");

                // Convert the string data to byte data using ASCII encoding.
                byte[] byteData = Encoding.ASCII.GetBytes(message.MessageString() + "#");

                // Begin sending the data to the remote device.
                client.BeginSend(byteData, 0, byteData.Length, 0,
                                 new AsyncCallback(SendCallback), state);
            }
            catch (Exception e)
            {
                Logger.Log(Logger.LogMode.MainLogProcessLogAndError, state.process.GetProcessDefaultName(), "AsynchronousSender.Send()", e.ToString(), "Error");
            }
        }
예제 #8
0
        /*
         * AcceptCallback
         * This function is called by the socket when the connection was established
         */

        /**********************************************************************************************//**
        * Callback, called when the accept.
        *
        * \author  Ilan Hindy
        * \date    29/09/2016
        *
        * \param   ar  The archive.
        *
        **************************************************************************************************/

        public static void AcceptCallback(IAsyncResult ar)
        {
            // Get the socket that handles the client request (The receive socket).
            SocketStateObject state    = (SocketStateObject)ar.AsyncState;
            Socket            listener = state.listenSocket;
            Socket            handler  = listener.EndAccept(ar);

            try
            {
                state.workSocket = handler;

                //Create asynchronouse reader by the process
                state.process.AddAsynchronousReader(state);

                // Signal the main thread to continue.
                state.allDone.Set();
            }
            catch (Exception e)
            {
                Logger.Log(Logger.LogMode.MainLogProcessLogAndError, state.process.GetProcessDefaultName(), "AsynchronousSocketListener.AcceptCallback()", e.ToString(), "Error");
            }
        }