Server.cs

For easier viewing download the code on the my code page or copy and paste into your IDE.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net.Sockets;
using System.Net;

namespace Capstone_Networking_Project_Test_0
{
    class Server
    {
        private Client[] clients = new Client[INetwork_Utils.MAX_CLIENTS];
        private int numClients = -1;//0 index so client 0 is first client
        private UdpClient listener;
        private Track_Data track;
        public Server()
        {
            track = new Track_Data();
            listener = new UdpClient();
            IPEndPoint localEP = new IPEndPoint(IPAddress.Any, INetwork_Utils.PORT_NUM);
            listener.Client.Bind(localEP);
            Listen();
        }

        private void Listen()
        {
            Console.WriteLine("Server online...");
            bool newClient;
            IPEndPoint recvFrom;
            while (true)
            {
                newClient = true;
                recvFrom = new IPEndPoint(IPAddress.Any, INetwork_Utils.PORT_NUM);
                byte[] recieved = listener.Receive(ref recvFrom);
                for (int i = 0; i < clients.Length; i++)
                {
                    if (!(clients[i] is null) && IPEndPoint.Equals(recvFrom, clients[i].Ep) && clients[i].IsConnected)
                    {
                        newClient = false;
                        string converted = ASCIIEncoding.ASCII.GetString(recieved);
                        //UpdateTrack(i, converted, recvFrom);
                        UpdateTrack(i, converted);
                        break;
                    }
                }
                #region New Client
                if (newClient)
                {
                    Console.WriteLine("New Client");
                    if (numClients >= INetwork_Utils.MAX_CLIENTS)
                    {
                        string msg = INetwork_Utils.DISCONNECT + "";
                        byte[] data = ASCIIEncoding.ASCII.GetBytes(msg);
                        listener.Send(data, data.Length, recvFrom);
                    }
                    else
                    {
                        numClients++;
                        int i;
                        for ( i = 0; i < clients.Length; i++) 
                        {
                            if (clients[i] is null || !clients[i].IsConnected)
                                break;
                        }
                        clients[i] = new Client(recvFrom, numClients);//write the new client over the old
                        FreshClient(recvFrom);
                    }
                }
                #endregion

            }
        }

        private void UpdateTrack(int id, string msg)
        {
            int i, val, act;
            string[] arr = msg.Split(INetwork_Utils.DELIM);
            if (!int.TryParse(arr[0], out act))
                Console.WriteLine("Message corrupted didnt find the action");

            switch (act)
            {
                case INetwork_Utils.TURN://TURN;index;direction
                    #region Adjust turnout
                    if (arr.Length == 3 && int.TryParse(arr[1], out i) && int.TryParse(arr[2], out val))
                    {
                        Console.WriteLine("Sent from Client " + id + ": Turnout " + i + " was turned to face " + val);
                        track.AdjustTurnout(i, val);
                        SendToAllExcept(msg, id);
                    }
                    else
                    {
                        Console.WriteLine("Message corrupted couldnt change turnout");
                        //tell the client
                    }
                    break;
                #endregion
                case INetwork_Utils.SPEED://SPEED;index;speed
                    #region Adjust Speed
                    if (arr.Length == 3 && int.TryParse(arr[1], out i) && int.TryParse(arr[2], out val))
                    {
                        Console.WriteLine("Sent from Client " + id + ":Train " + i + " changed speed to " + val);
                        track.ChangeSpeed(clients[id].TrainIndex, val);
                        SendToAllExcept(msg, id);
                    }
                    else
                    {
                        Console.WriteLine("Message corrupted couldnt update speed");
                        //tell the client
                    }
                    #endregion
                    break;
                case INetwork_Utils.ENTER://ENTER;index in;index out
                    #region Adjust sections
                    int direction;
                    if (arr.Length == 4 && int.TryParse(arr[1], out i) && int.TryParse(arr[2], out val) && int.TryParse(arr[3], out direction))
                    {
                        track.EnterSection(i, direction);
                        track.ExitSection(val);
                        Console.WriteLine("Sent from Client " + id + ": exiting section " + val + " entering section " + i);
                        SendToAllExcept(msg, id);
                    }
                    else
                    {
                        Console.WriteLine("Message corrupted couldnt update sections");
                        Console.WriteLine("Corrupted message = " + msg);

                        //tell the client
                    }
                    #endregion
                    break;
                case INetwork_Utils.NEW_TRAIN://NEW_TRAIN;Train id;Train speed
                    #region Creating a new train
                    if (arr.Length == 4 && int.TryParse(arr[1], out i) && int.TryParse(arr[2], out val))
                    {
                        string username = arr[3];
                        Console.WriteLine("Sent from Client " + id + ": Added a new train with id " + i + " and speed " + val + " and username " + username);
                        int index = track.MakeTrain(i, val, username);
                        clients[id].TrainIndex = index;
                        SendToAllExcept(msg, id);
                    }
                    else
                    {
                        Console.WriteLine("Message corrupted couldnt update speed");
                        //tell the client
                    }
                    break;
                #endregion
                case INetwork_Utils.DISCONNECT://DISCONNECT;train id, section to open
                    #region Remove a Client
                    Console.WriteLine("Client " + id + " is trying to disconnect");
                    int trainID = int.Parse(arr[1]);
                    val = int.Parse(arr[2]);
                    RemoveClient(id);
                    int removedAt = track.RemoveTrain(trainID);
                    foreach (Client c in clients)
                    {
                        if (!(c is null) && c.TrainIndex > removedAt)
                            c.TrainIndex--;
                    }
                    track.ExitSection(val);
                    SendToAllExcept(msg, id);
                    break;
                    #endregion
            }
        }

        private void RemoveClient(int id)
        {
            clients[id].IsConnected = false;
            numClients--;
            Console.WriteLine("Number of clients left =" + numClients);
            if(numClients<0)
            {
                track.ResetTrack();
            }
            Console.WriteLine("Disconnected Client:" + id);
        }

        private void FreshClient(IPEndPoint ep)
        {
            string msg = track.GetTurns();
            byte[] data = Encoding.ASCII.GetBytes(msg);
            listener.Send(data, data.Length, ep);
            Console.WriteLine("Sending turnouts as: " + msg);

            msg = track.GetSections();
            data = Encoding.ASCII.GetBytes(msg);
            listener.Send(data, data.Length, ep);
            Console.WriteLine("Sending sections as: " + msg);

            msg = INetwork_Utils.LOC+"";
            data = Encoding.ASCII.GetBytes(msg);//used to request locations of existing trains
            string trainData = "";
            listener.Client.ReceiveTimeout = INetwork_Utils.TIMEOUT;
            for (int i = 0; i < INetwork_Utils.MAX_CLIENTS; i++)
            {
                if (!(clients[i] is null) && clients[i].IsConnected)
                {
                    IPEndPoint addr = clients[i].Ep;
                    if (!(addr.Equals(ep)))//dont want to ask the client we are currently arranging
                    {
                        int count = 0;
                    retry://this section should be threaded...send messages to main thread and queue if they arent location messages 
                        listener.Send(data, data.Length, addr);
                        try
                        {
                            byte[] recvd = listener.Receive(ref addr);
                            trainData += (Encoding.ASCII.GetString(recvd)) + INetwork_Utils.DELIM + track.GetNameAt(clients[i].TrainIndex) + INetwork_Utils.DELIM + track.SpeedAt(clients[i].TrainIndex) + INetwork_Utils.DELIM;
                        }
                        catch (SocketException)
                        {
                            Console.WriteLine("listen failed");
                            count++;
                            if(count<=5)
                                goto retry;//try 5 times then disconnect client
                        }
                        if (count == 6)
                        {
                            data = ASCIIEncoding.ASCII.GetBytes(INetwork_Utils.DISCONNECT+"");
                            listener.Send(data, data.Length, ep);
                        }
                        Console.WriteLine("Data after iteration " + i + trainData);
                    }
                }
            }
            listener.Client.ReceiveTimeout = Timeout.Infinite;
            if (trainData.Equals(""))
                trainData = INetwork_Utils.NONE;
            Console.WriteLine("Sending trains as: " + trainData);
            data = Encoding.ASCII.GetBytes(trainData);
            listener.Send(data, data.Length, ep);
        }

        private void SendToAllExcept(string msg, int index) 
        {
            byte[] data = ASCIIEncoding.ASCII.GetBytes(msg);
            for (int i = 0; i < INetwork_Utils.MAX_CLIENTS; i++)
            {
                if (!(clients[i] is null) && i != index && clients[i].IsConnected)
                {
                    listener.Send(data, data.Length, clients[i].Ep);
                    listener.Send(data, data.Length, clients[i].Ep);
                    listener.Send(data, data.Length, clients[i].Ep);
                    Console.WriteLine("sent " + msg + " to client " + i);
                }
            }
        }

    }
}
css.php