Exemple #1
0
        public Connection AcceptConnection()
        {
            var socket     = ServerSocket.AcceptTcpClient();
            var connection = new Connection(socket);

            Connections.Add(connection);
            return(connection);
        }
Exemple #2
0
 internal void Start()
 {
     ServerSocket.Start();
     while (true)
     {
         ClientSocket = ServerSocket.AcceptTcpClient();
         HandleAlarmClient client = new HandleAlarmClient();
         client.StartClient(ClientSocket, _parent);
     }
 }
        /// <summary>
        /// The main function Running in the thread.
        /// </summary>
        public virtual void Run()
        {
            // sockets to communicate to each of the islands
            var con = new TcpClient[NumIslands];

            // readers and writters for communication with each island
            var dataIn  = new BinaryReader[NumIslands];
            var dataOut = new BinaryWriter[NumIslands];



            // whether each client is working (and communicating with the server) or not
            var clientRunning = new bool[NumIslands];

            // initialize the Running status of all clients
            for (var x = 0; x < NumIslands; x++)
            {
                clientRunning[x] = true;
            }

            try
            {
                // create a server
                var tempTcpListener = new TcpListener(Dns.GetHostEntry(Dns.GetHostName()).AddressList[0], ServerPort);
                tempTcpListener.Start();
                ServerSocket = tempTcpListener;
            }
            catch (IOException)
            {
                State.Output.Fatal("Error creating a socket on port " + ServerPort);
            }

            // for each of the islands
            for (var x = 0; x < NumIslands; x++)
            {
                try
                {
                    // set up connection with the island
                    con[x] = ServerSocket.AcceptTcpClient();

                    // initialize the reader and the writer
                    dataIn[x]  = new BinaryReader(con[x].GetStream());
                    dataOut[x] = new BinaryWriter(con[x].GetStream());

                    // read the id
                    ConnectedIslandIds[x] = dataIn[x].ReadString().Trim();

                    State.Output.Message("Island " + ConnectedIslandIds[x] + " logged in");

                    // check whether the id appears in the information at the server
                    if (!Info.ContainsKey(ConnectedIslandIds[x]))
                    {
                        State.Output.Error("Incorrect ID (" + ConnectedIslandIds[x] + ")");
                        clientRunning[x] = false;
                        continue;
                    }

                    var ieii = (IslandExchangeIslandInfo)Info[ConnectedIslandIds[x]];

                    // redundant check, i know....
                    if (ieii == null)
                    {
                        State.Output.Error("Can't get IslandExchangeInfo for " + ConnectedIslandIds[x]);
                        clientRunning[x] = false;
                        continue;
                    }

                    // check whether an island with this id already registered with the server
                    if (ieii.Port >= 0)
                    {
                        State.Output.Error("Multiple islands are claiming the same ID (" + ConnectedIslandIds[x] + ")");
                        clientRunning[x] = false;
                        continue;
                    }

                    // send the number of ids that will be send through the communication link
                    dataOut[x].Write(ieii.NumIncoming);

                    // send the capacity of the Mailbox
                    dataOut[x].Write(ieii.MailboxCapacity);

                    dataOut[x].Flush();

                    // read the address and port of the island
                    ieii.Address = dataIn[x].ReadString().Trim();
                    ieii.Port    = dataIn[x].ReadInt32();

                    State.Output.Message("" + x + ": Island " + ConnectedIslandIds[x]
                                         + " has address " + ieii.Address + " : " + ieii.Port);

                    // re-insert the information in the hash table
                    // info.put( id, ieii );                                // unnecessary -- Sean
                }
                catch (IOException)
                {
                    State.Output.Error("Could not open connection #" + x);
                    clientRunning[x] = false;
                }
            }

            State.Output.ExitIfErrors();

            // By this time, all Mailboxes have been started and
            // they should be waiting for incoming messages. this is because
            // in order to send the server the information about the address and port
            // of the Mailbox, they have to start them first. This is the reason
            // that makes us be able to start connecting without other synchronization
            // stuff right at this point.

            // Now, I think, we've got a 1:1 mapping of keys to items in the info hashtable
            // So we tell everyone who they will communicate to

            for (var x = 0; x < NumIslands; x++)
            {
                if (clientRunning[x])
                {
                    var ieii = (IslandExchangeIslandInfo)Info[ConnectedIslandIds[x]];

                    if (ieii == null)
                    {
                        State.Output.Warning("There is no information about island " + ConnectedIslandIds[x]);
                        clientRunning[x] = false;
                        continue;
                    }

                    try
                    {
                        // send the Synchronous, Modulo, Offset and size information to the current islands
                        if (Synchronous)
                        {
                            dataOut[x].Write(1);
                        }
                        else
                        {
                            dataOut[x].Write(0);
                        }
                        dataOut[x].Write(ieii.Modulo);
                        dataOut[x].Write(ieii.Offset);
                        dataOut[x].Write(ieii.Size);

                        // send the number of address-port pairs that will be sent
                        dataOut[x].Write(ieii.NumMig);

                        for (var y = 0; y < ieii.NumMig; y++)
                        {
                            var temp = (IslandExchangeIslandInfo)Info[ieii.MigratingIslandIds[y]];

                            if (temp == null)
                            {
                                State.Output.Warning("There is incorrect information on the island " + ConnectedIslandIds[x]);
                                dataOut[x].Write(" ");
                                dataOut[x].Write(-1);
                            }
                            else
                            {
                                State.Output.Message("Island " + ConnectedIslandIds[x] + " should connect to island "
                                                     + ieii.MigratingIslandIds[y] + " at " + temp.Address + " : " + temp.Port);

                                dataOut[x].Write(temp.Address);
                                dataOut[x].Write(temp.Port);
                            }
                        }
                        dataOut[x].Flush();
                    }
                    catch (IOException)
                    {
                        // other errors while reading
                        State.Output.Message("Server: Island " + IslandIds[x] + " dropped connection");
                        clientRunning[x] = false;
                        continue;
                    }
                    catch (NullReferenceException)
                    {
                        // other errors while reading
                        State.Output.Message("Server: Island " + IslandIds[x] + " dropped connection");
                        clientRunning[x] = false;
                        try
                        {
                            dataIn[x].Close();
                            dataOut[x].Close();
                            con[x].Close();
                        }
                        catch (IOException)
                        {
                        }
                        continue;
                    }
                }
            }

            try
            {
                // Next we wait until everyone acknowledges this
                foreach (BinaryReader t in dataIn)
                {
                    t.ReadString();
                }

                // Now we tell everyone to start Running
                foreach (BinaryWriter t in dataOut)
                {
                    t.Write(RUN);
                    t.Flush();
                }
            }
            catch (IOException)
            {
            }

            // Okay we've sent off our information.  Now we wait until a client
            // tells us that he's found the solution, or until all the clients
            // have broken connections

            for (var x = 0; x < con.Length; x++)
            {
                try
                {
                    con[x].ReceiveTimeout = FOUND_TIMEOUT;
                }
                catch (SocketException)
                {
                    State.Output.Error("Could not set the connect with island " + x + " to non-blocking.");
                }
            }

            var shouldExit = false;

            while (!shouldExit)
            {
                // check whether there is at least one client Running
                // otherwise the server might continue functioning just because the last client crashed or finished connection
                shouldExit = true;
                for (var x = 0; x < dataOut.Length; x++)
                {
                    if (clientRunning[x])
                    {
                        shouldExit = false;
                        break;
                    }
                }
                if (shouldExit)
                {
                    break;
                }

                // sleep a while
                try
                {
                    Thread.Sleep(new TimeSpan((Int64)10000 * SLEEP_TIME));
                }
                catch (ThreadInterruptedException)
                {
                }

                for (var x = 0; x < dataOut.Length; x++)
                {
                    if (clientRunning[x])
                    {
                        // initialize ww
                        string ww;

                        // check to see if he's still up, and if he's
                        // sent us a "I found it" signal
                        try
                        {
                            ww = dataIn[x].ReadString().Trim();
                        }
                        //catch (System.IO.IOException e)
                        //{
                        //    // means that it run out of time and got no message,
                        //    // so it should just continue with the other sockets
                        //    continue;
                        //}
                        catch (IOException)
                        {
                            // other errors while reading
                            State.Output.Message("Server: Island " + IslandIds[x] + " dropped connection");
                            clientRunning[x] = false;
                            continue;
                        }
                        catch (NullReferenceException)
                        {
                            // other errors while reading
                            State.Output.Message("Server: Island " + IslandIds[x] + " dropped connection");
                            clientRunning[x] = false;
                            try
                            {
                                dataIn[x].Close();
                                dataOut[x].Close();
                                con[x].Close();
                            }
                            catch (IOException)
                            {
                            }
                            catch (Exception)
                            {
                            }
                            continue;
                        }

                        if (ww == null) // the connection has been broken
                        {
                            State.Output.Message("Server: Island " + IslandIds[x] + " dropped connection");
                            clientRunning[x] = false;
                            try
                            {
                                dataIn[x].Close();
                                dataOut[x].Close();
                                con[x].Close();
                            }
                            catch (IOException)
                            {
                            }
                        }
                        else if (ww.Equals(IslandExchange.FOUND))
                        // he found it!
                        {
                            // inform everyone that they need to shut down --
                            // we do not need to wrap
                            // our PrintLn statements in anything, they just
                            // return even if the client has broken the connection
                            for (var y = 0; y < dataOut.Length; y++)
                            {
                                if (clientRunning[y])
                                {
                                    try
                                    {
                                        dataOut[y].Write(GOODBYE);
                                        dataOut[y].Close();
                                        dataIn[y].Close();
                                        con[y].Close();
                                    }
                                    catch (IOException)
                                    {
                                    }
                                }
                            }
                            // now we can just get out of all this and
                            // quit the thread
                            shouldExit = true;
                            break;
                        }
                        else if (ww.Equals(IslandExchange.SYNC))
                        {
                            WhoIsSynchronized[x] = true;

                            var complete_synchronization = true;

                            for (var y = 0; y < NumIslands; y++)
                            {
                                complete_synchronization = complete_synchronization && (!clientRunning[y] || WhoIsSynchronized[y]);
                            }

                            // if the number of total Running islands is smaller than the
                            // number of islands that ask for synchronization, let them continue
                            // Running
                            if (complete_synchronization)
                            {
                                for (var y = 0; y < NumIslands; y++)
                                {
                                    // send the okay message (the client can continue executing)
                                    if (clientRunning[y])
                                    {
                                        try
                                        {
                                            dataOut[y].Write(IslandExchange.OKAY);
                                            dataOut[y].Flush();
                                        }
                                        catch (IOException)
                                        {
                                        }
                                    }
                                    // reset the who_is_synchronized variable
                                    WhoIsSynchronized[y] = false;
                                }
                            }
                        }
                    }
                }
            }
            State.Output.Message("Server Exiting");
        }
Exemple #4
0
        /// <summary>
        /// The main functionality of the Mailbox:
        /// waiting for incoming messages and dealing with the incoming immigrants
        /// </summary>
        public virtual void Run()
        {
            // wait for the "NumIncoming" incoming connections from different islands, and initialize
            // the sockets and the readers to communicate with (receive messages from) them. All the
            // sockets are set to be non-blocking, such that they can be checked alternatively without
            // waiting for messages on a particular one.
            for (var x = 0; x < NumIncoming; x++)
            {
                try
                {
                    InSockets[x] = ServerSocket.AcceptTcpClient();

                    BinaryWriter dataOutput;

                    if (CompressedCommunication)
                    {
                        /*
                         * dataInput[x] = new DataInputStream(new CompressingInputStream(inSockets[x].getInputStream()));
                         * dataOutput = new DataOutputStream(new CompressingOutputStream(inSockets[x].getOutputStream()));
                         */
                        var compressedo = Output.MakeCompressingOutputStream(InSockets[x].GetStream());
                        var compressedi = Output.MakeCompressingInputStream(InSockets[x].GetStream());
                        if (compressedi == null || compressedo == null)
                        {
                            State.Output.Fatal("You do not appear to have JZLib installed on your system, and so may must have compression turned off for IslandExchange.  " + "To get JZLib, download from the ECJ website or from http://www.jcraft.com/jzlib/");
                        }

                        DataInput[x] = new BinaryReader(compressedi);
                        dataOutput   = new BinaryWriter(compressedo);
                    }
                    else
                    {
                        DataInput[x] = new BinaryReader(InSockets[x].GetStream());
                        dataOutput   = new BinaryWriter(InSockets[x].GetStream());
                    }

                    // send my id, then read an id
                    dataOutput.Write(MyId);
                    dataOutput.Flush();
                    IncomingIds[x] = DataInput[x].ReadString().Trim();

                    State.Output.Message("Island " + IncomingIds[x] + " connected to my Mailbox");

                    // set the socket to non-blocking
                    InSockets[x].ReceiveTimeout = CHECK_TIMEOUT;
                    Running[x] = true;
                }
                catch (IOException e)
                {
                    Running[x] = false;
                    State.Output.Fatal("An exception was generated while creating communication structures for island " + x + ".  Here it is: " + e);
                }
            }

            State.Output.Message("All islands have connected to my client.");

            // variable used for deciding (based on the synchronized variable "syncVar") when to exit
            bool shouldExit;

            // enter the main loop
            do
            {
                // wait some (do not check all the time, cause it would be a waste of time and computational resources)
                try
                {
                    Thread.Sleep(new TimeSpan((Int64)10000 * SLEEP_BETWEEN_CHECKING_FOR_IMMIGRANTS));
                }
                catch (ThreadInterruptedException)
                {
                }

                // for each of the connections established with the islands
                for (var x = 0; x < NumIncoming; x++)
                {
                    if (Running[x])
                    {
                        try
                        {
                            // enter an infinite loop to receive all the messages form the "x"s island
                            // it will exit the loop as soon as there are no more messages coming from
                            // the "x"s island (non-blocking socket)
                            while (true)
                            {
                                // read the subpop where the immigrants need to be inserted. In case there
                                // is no incoming message, an exception will be generated and the infinite loop
                                // will be exited (the Mailbox will search the next socket (communication link)
                                // for incoming messages
                                var subpop = DataInput[x].ReadInt32();

                                // if it gets to this point, it means that a number of individuals will be sent
                                // it is the time to set up the receiving storages

                                // set the socket to blocking for reading the individuals
                                try
                                {
                                    InSockets[x].ReceiveTimeout = 0;
                                }
                                catch (SocketException)
                                {
                                    State.Output.Warning("Could not set the socket to blocking while receiving individuals in the Mailbox.");
                                }

                                // how many individuals will be received in the current dialogue?
                                var how_many_to_come = DataInput[x].ReadInt32();

                                if (Chatty)
                                {
                                    State.Output.Message("Receiving " + how_many_to_come
                                                         + " immigrants for subpop " + subpop + " from island " + IncomingIds[x]);
                                }

                                // synchronize on the immigrants (such that other threads cannot access it during its
                                // being modified)
                                lock (Immigrants)
                                {
                                    // in case the immigrants buffer was emptied, the person2die is not reset (it is not public)
                                    // so we have to reset it now
                                    if (NumImmigrants[subpop] == 0)
                                    {
                                        // if it was reset
                                        NextIndexPosition[subpop] = 0; // reset the person2die[x]
                                    }
                                    // loop in order to receive all the incoming individuals in the current dialogue
                                    for (var ind = 0; ind < how_many_to_come; ind++)
                                    {
                                        // read the individual
                                        try
                                        {
                                            // read the immigrant in the storage
                                            Immigrants[subpop][NextIndexPosition[subpop]] =
                                                State.Population.Subpops[subpop].Species.NewIndividual(State, DataInput[x]);

                                            //state.Output.Message( "Individual received." );

                                            // increase the queue index
                                            if (NextIndexPosition[subpop] == Immigrants[subpop].Length - 1)
                                            {
                                                NextIndexPosition[subpop] = 0;
                                            }
                                            else
                                            {
                                                NextIndexPosition[subpop]++;
                                            }

                                            // can increment it without synchronization, as we do synchronization on the immigrants
                                            if (NumImmigrants[subpop] < Immigrants[subpop].Length)
                                            {
                                                NumImmigrants[subpop]++;
                                            }
                                        }
                                        catch (IOException)
                                        {
                                            // i hope it will also never happen :)
                                            State.Output.Message("IO exception while communicating with an island");
                                            Running[x] = false;
                                            continue;
                                        }
                                        catch (FormatException)
                                        {
                                            // it happens when the socket is closed and cannot be doing any reading
                                            State.Output.Message("IO exception while communicating with an island");
                                            Running[x] = false;
                                            continue;
                                        }
                                    }
                                } // end synchronized block on "immigrants"

                                // set the socket to non-blocking (after current set of immigrants is over)
                                try
                                {
                                    InSockets[x].ReceiveTimeout = CHECK_TIMEOUT;
                                }
                                catch (SocketException)
                                {
                                    State.Output.Warning("Could not set the socket to non-blocking while receiving individuals in the Mailbox.");
                                }
                            }
                        }
                        //catch (InterruptedIOException e) // BRS : TODO : Find the .NET exception that we want to catch here?
                        //{
                        //    // here everything is ok
                        //    // just that there were no messages
                        //}
                        catch (IOException)
                        {
                            // now this is not nice
                            // report the error so that the programmer can fix it (hopefully)
                            State.Output.Message("IO exception while communicating with an island");
                            Running[x] = false;
                        }
                        catch (FormatException) // BRS : TODO : Verify that this is the .NET exception to expect?
                        {
                            // error received when some sockets break
                            State.Output.Message("Socket closed");
                            Running[x] = false;
                        }
                    }
                }

                // again with synchronization, try to access the syncVar to check whether the Mailbox needs to finish
                // Running (maybe some other island already found the perfect individual, or the resources of the current
                // run have been wasted)
                lock (syncVar)
                {
                    // get the value of the syncVar. If it is true, we should exit.
                    shouldExit = syncVar[0];
                }
            }while (!shouldExit);

            // close the sockets (don't care about the Running, but deal with exceptions)
            try
            {
                // close the ServerSocket
                ServerSocket.Stop();
            }
            catch (IOException)
            {
            }
            for (var x = 0; x < NumIncoming; x++)
            {
                try
                {
                    // close the sockets to communicate (receive messages) with the other islands
                    InSockets[x].Close();
                }
                catch (IOException)
                {
                    continue;
                }
            }
        }