A Traffic Client Server Model

A traffic client server model is a an application of client-server model. It uses the socket programming. I have used C#.net as a front end and SQL Express as a back end. The problem definition and solution is given below:

Download the Full Solution <<

Client Model:

TrafficClient.cs

/***************************************************************
                    Quazi Mainul Hasan
               
***************************************************************/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.IO;
using System.Xml;

namespace TrafficClient
{
    public partial class TrafficClientServerMenu : Form
    {
        private static TcpClient m_tcpClient;
        private NetworkStream m_networkStream;
        private StreamWriter m_streatWriter;
        private StreamReader m_streamReader;

       // This is the constructor for the class.
        public TrafficClientServerMenu()
        {
            InitializeComponent();                        // Initializing component of the form
            this.disconnectToolStripMenuItem.Enabled = false;                // Disabling the disconnect button initially
        }

        // This Exit eventhandler will terminate the whole program.
        private void ExitToolsStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();   //It will terminate the application.
        }

        private void connectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (portNumberTextBox.Text.Trim().ToString()=="")
            {
                MessageBox.Show("Set the port number first, the same port address in the server.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                portNumberTextBox.Focus();
                return;
            }
            try
            {
                System.Windows.Forms.Cursor.Current = Cursors.WaitCursor;        // Show wait cursor in the window

                m_tcpClient = new TcpClient("localhost", Int32.Parse(portNumberTextBox.Text.Trim().ToString())); // this will try to connect to the port in the server
                this.connectToolStripMenuItem.Enabled = false;  //after connection this will disable the connect menu
                this.disconnectToolStripMenuItem.Enabled = true; // it will enable the menu strip for disconnection
                System.Windows.Forms.Cursor.Current = Cursors.Arrow;        // shows the default cursor in the window.
                MessageBox.Show("Successfully  connected.","Information", MessageBoxButtons.OK, MessageBoxIcon.Information);   // Shows confirmation message for successfull connection.
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString(),"Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

        }

        //Even handler for disconnect button. This will disconnect the connection betwen client and serve.
        private void disconnectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Connection disconnected.","Information", MessageBoxButtons.OK,  MessageBoxIcon.Information);        // Showing message that the connection is disconnected.
            this.disconnectToolStripMenuItem.Enabled = false;                // Disable the disconnect button
            this.connectToolStripMenuItem.Enabled = true;                // Enable the connect button
            //if (m_tcpClient.Connected)
            //{
                m_tcpClient.Close();    //this will disconnect the connection with the server from client.
            //}
            if(m_streamReader != null || m_streatWriter != null || m_networkStream != null)        //Checks whther any of them is null or not, if
            {
                m_streamReader.Close();
                m_streatWriter.Close();
                m_networkStream.Close();
            }
            this.roadComboBox.SelectedIndex = -1;            // Set the dropdown box to it's initial stage. No selection will be there in the dropdown.
            this.outputTrafficTextBox.Text = "";                // Clearing the fields.
            this.dataGridView1.DataSource = null;                // Reset the datagridview.
        }

        //event handler for update button, this event handler will request data form the server on a specific road selected from the roadCombobox.
        private void updateButton_Click(object sender, EventArgs e)
        {
            string situationOfRoad="";
            if (m_tcpClient==null)   //checks whether client is connected to the server or not.
            {
                MessageBox.Show("Please connect to the server first.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            if (this.roadComboBox.Text=="")         //checks whether a road is selected or not.
            {
                MessageBox.Show("Please select a road to get the traffic update.","Information",MessageBoxButtons.OK,MessageBoxIcon.Information);
                this.roadComboBox.Focus();
                return;
            }
            if (m_tcpClient.Connected)
            {
                m_networkStream = m_tcpClient.GetStream();         //get a Network stream from the server
                m_streamReader = new StreamReader(m_networkStream);    // create a stream reader for reading data from the server.
                m_streatWriter = new StreamWriter(m_networkStream);    // create a stream writer for sending request to the server.

                m_streatWriter.WriteLine(roadComboBox.Text.ToString());     //writing data in the stream
                m_streatWriter.Flush();                                             //sending request to the server

                situationOfRoad = m_streamReader.ReadLine();                        // Get data form the server
                this.ShowDataInClientSide(situationOfRoad);              // Shoing graphical representation of the traffic data.

                outputTrafficTextBox.Text = situationOfRoad;
            }
        }

        private void ShowDataInClientSide(string situationOfRoad)
        {
            char[] separator ={ ',' };
            string[] parsedValue = situationOfRoad.Split(separator);        // Parsing the traffic data from the server which is received from the server as a string.
            listBox1.Items.Clear();                    // Clearing the items in the listbox control.
            for (int i = 0; i < parsedValue.Length; i++)           
            {
                listBox1.Items.Add(parsedValue[i].Trim().ToString());        // This loop will add the parsed value in the list box.

            }

            DataTable trafficStatus= new DataTable("TrafficUpdate");            //Creats a new data table  as a datasource for datagridview1
            DataColumn col1 = new DataColumn("Intersection", typeof(string));        // Creats a colum with name Intersection of type string
            DataColumn col2 = new DataColumn("Status", typeof(Bitmap));        //Creats a column with name Status of type Bitmap
            //DataGridTableStyle tableStyle = new DataGridTableStyle();

            trafficStatus.Columns.Add(col1);
            trafficStatus.Columns.Add(col2);            // Adding the columns in the datatable.
            for (int i = 0; i < parsedValue.Length; i++)
            {
                DataRow dr;
                if (parsedValue[i].ToString() != "")            // Checks whether there is any new line in the parsed value or not.
                {         

                    dr = trafficStatus.NewRow();            // Adds a new row to the data table.
                    dr["Intersection"] = parsedValue[i].Trim().ToString();    // Sets the value of the column Intersection in this new row.
                    dr["Status"] = DrawBitMap(parsedValue[i]);        //Set the bitmap value in the column Status in this row.
                    trafficStatus.Rows.Add(dr);            //Adding the row in the table

                }
                else continue;                // If there is a new line it will no add a row in the data table.
            }
            trafficStatus.AcceptChanges();            // This function will save the data in the data table and make the status of each row to default instead of added.
            this.dataGridView1.DataSource = null;            // This will reset the datasource of of the datagridview
            dataGridView1.AllowUserToAddRows = false;        // This will disable the add row option in the gridview from client side explicitly.
            this.dataGridView1.DataSource = trafficStatus;        // Sets the data source for the gridview.
            dataGridView1.Columns["Status"].Width = 270;        // Sets the width of the column status in the gridview.
            dataGridView1.Columns["Intersection"].Width = 300;    // Sets the width of the column status in the gridview.
        }

        private Bitmap DrawBitMap(string temp)
        {
            Bitmap statusBitMap = new Bitmap(250, 20);        // Creats a bitmap object with specific width and height.
            Color col = new Color();
            if (temp.Contains("Normal"))            // true, if the parsed string has the value Normal.
            {
                col = Color.Green;                // this will set the color for filling the bitmap.
            }
            if (temp.Contains("Slow"))                // true, if the parsed string has the value Slow
            {
                col = Color.Navy;                // this will set the color for filling the bitmap.
            }
            if (temp.Contains("Congested"))            // true, if the parsed string has the value Congested
            {
                col = Color.Purple;                // this will set the color for filling the bitmap.
            }
            if (temp.Contains("Accident"))            // true, if the parsed string has the value Accident
            {
                col = Color.Red;                // this will set the color for filling the bitmap.
            }

           // This loop will fill the bitmap with the selected color.
            for (int i = 0; i < 250; i++)
            {
                for (int j = 0; j < 20; j++)
                {
                    statusBitMap.SetPixel(i, j,col);              // Set pixel to that a specific color.
                }
            }
            return statusBitMap;
        }

    }
}

 

 

 

Server Model

TrafficServer.cs

 

/***************************************************************
                    Quazi Mainul Hasan

***************************************************************/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.IO;
using System.Timers;
using System.Threading;

namespace TrafficServer
{
    public partial class Server : Form
    {
        private TcpListener m_tcpListener;            // Listens in a specific port.
        private Socket m_serverSocket;            // server socket for creating socket in the server side to connect to the client side.
        private NetworkStream m_networkStream;        // For exchanging data through steram.
        private StreamReader m_streamReader;            // for reading data from the stream
        private StreamWriter m_streamWriter;            // for writing data in the stream
        private DataAccessLayer m_dataAccessLayer;        // This class is for accessing data to the database.
        private System.Timers.Timer m_timer;            // timer is used for updating data in the database after a certain interavl.
        private double delayTime = 5000;            // Initially time interval is set to 5 sec.
        private Thread m_WrokerThread;            // This thread is used for sending and receiving data
        private string dataFromClient;                // The client data will be stored in this variable.

        /// <summary>
        /// Constructor for this class
        /// </summary>
        public Server()
        {
            InitializeComponent();
            m_timer = new System.Timers.Timer(delayTime);                    // this instantiate the timer with the interval.
            m_timer.Enabled = true;                                            // making timer enables.
            m_timer.Elapsed += new ElapsedEventHandler(m_timer_Elapsed);    // adding the evenhandler for the timer.
            m_timer.Start();                                                // this will start the timer
            m_dataAccessLayer = new DataAccessLayer();                        //instantiate an object of dataaccesslayer

        }

        // This even handler will set the time interval.
        private void setTimebutton_Click(object sender, EventArgs e)
        {

            m_timer.Interval = Convert.ToDouble(this.timeIntervalUpDown.Value);

        }

        // This event handler will update the traffic data in the database randomly.
        void m_timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            m_dataAccessLayer.UpdateData();                   // Calls the function update data in the DataAccessLayer class.
        }

        // This function will be handled by a thread and will handle the client data.
        private void WorkerThread()
        {
            while (true)
            {
                try
                {
                    dataFromClient = m_streamReader.ReadLine();                // This will wait for the data from the client.
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Server Disconnected.");
                    return;
                }

                if (dataFromClient != null)
                {
                    Console.WriteLine("Traffic request for road" + dataFromClient + " is received");
                    m_streamWriter.WriteLine(this.GetTrafficInformation(dataFromClient));    // This will write the traffic data in the stream
                    m_streamWriter.Flush();                    // This will send the traffic data to the client
                    Console.WriteLine("Traffic update for road" + dataFromClient + " is send to client");
                }
                else
                {
                    m_serverSocket = m_tcpListener.AcceptSocket();            // this will connect to the client through server socket.

                    m_networkStream = new NetworkStream(m_serverSocket);        // The will create a stream for exchanging data between client and server.
                    m_streamReader = new StreamReader(m_networkStream);        // This will create a stream reader
                    m_streamWriter = new StreamWriter(m_networkStream);        // This will create a stream writer.
                }

            }

        }

        // This eventhandler will start the server in a specific port and when a client is received it will accept the request and will instantiate a thread to handle the data exchange.
        private void startButton_Click(object sender, EventArgs e)
        {
            string dataFromClient;

            if (m_tcpListener == null)
            {
                if (portTextBox.Text.Trim().ToString()!="")
                {
                    Int32 portNumber = Int32.Parse(portTextBox.Text.Trim().ToString());
                    if (portNumber < 1024)
                    {
                        MessageBox.Show("Port number must be greater than 1024.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        return;
                    }
                    m_tcpListener = new TcpListener(portNumber);        // This will listen to a specific port number
                    m_tcpListener.Start();                // Server will wait for the client request
                    MessageBox.Show("Server is started", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);

                }
                else
                {
                    MessageBox.Show("Port number canot be empty", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    portTextBox.Focus();
                    return;
                }

            }

            responseTextBox.Text = "Waiting for the client request..." + Environment.NewLine;
            m_serverSocket = m_tcpListener.AcceptSocket();        // This will create a connection with the client.

            m_networkStream = new NetworkStream(m_serverSocket);
            m_streamReader = new StreamReader(m_networkStream);
            m_streamWriter = new StreamWriter(m_networkStream);

            try
            {
                if (m_serverSocket.Connected)            // Checks whether the connection is established or not.
                {
                    responseTextBox.Text += "Connection is established with the client...";
                    m_WrokerThread = new Thread(new ThreadStart(WorkerThread));        // Creates a new thread for handling data exchange.
                    m_WrokerThread.Start();                                  // This will start the thread.

                }
                else
                {
                    //m_serverSocket.Close();
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
            finally
            {
                // m_serverSocket.Close();

            }
        }

        //This function will get the traffic data from the data base.
        private string GetTrafficInformation(string dataFromClient)
        {

            DataTable roadInfoDT = m_dataAccessLayer.SelectData(dataFromClient);    // Use the DataAccessLayer class to retrieve data.
            string roadCondition = "";
            foreach (DataRow row in roadInfoDT.Rows)
            {
                roadCondition += row["Status"] + " at intersection between " + row["Highway1"].ToString() + " and " + row["Highway2"].ToString() + ", ";  // Creating a string for sending over the stream to the client.

            }
            roadCondition = roadCondition.Remove(roadCondition.Length - 1, 1);            // This removes the last comma in the string.

            return roadCondition;

        }

        // This event handler terminate worker thread and will exit the application.
        private void Server_FormClosed(object sender, FormClosedEventArgs e)
        {
            m_WrokerThread.Abort();
            Application.Exit();
        }

        // This event handler closes the server socket and exit application.
        private void stopButton_Click(object sender, EventArgs e)
        {
            if (m_serverSocket != null)
            {
                m_serverSocket.Close();
            }
            m_WrokerThread.Abort();

            Application.Exit();
        }

    }
}

 

Data Access Layer

DataAccessLayer.cs

/***************************************************************
                    Quazi Mainul Hasan

***************************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using System.Data;
using System.Configuration;

namespace TrafficServer
{
    /// <summary>
    /// This is class used to access data in the database.  
    /// </summary>
    public class DataAccessLayer
    {

        private string m_connectionString = @"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\TrafficDatabase.mdf;Integrated Security=True;User Instance=True";     // This is the connection string to make connection to the sql database.
        private SqlConnection m_sqlConnection;            // SqlConnection class is used to establish the connection.
        private SqlDataAdapter m_sqlDataAdapter;        // SqlDataAdapter is used to fill the dataset based on the select query.

        /// <summary>
        /// Constructor for the class.
        /// </summary>
        public DataAccessLayer()
        {
            m_sqlConnection = new SqlConnection(m_connectionString); // Create a new instance of sqlconnection.

        }

        /// <summary>
        ///This function retrives data from the table "RoadInformation," fills the table with data and return that table.
        /// </summary>
        /// <param name="roadName"></param>
        /// <returns></returns>
        public DataTable SelectData(string roadName)
        {
            DataTable roadInfoDT = new DataTable("RoadInfo");        //creates a table with name "RoadInfo"
            string selectString = "Select * from RoadInformation where Highway1='" + roadName + "' or Highway2='" + roadName + "'";        // Select query for retreving data.
            m_sqlConnection.Open();                    //creates a connection with the database.
            m_sqlDataAdapter = new SqlDataAdapter(selectString, m_sqlConnection);    // Instantiating the sqladapter.
            m_sqlDataAdapter.Fill(roadInfoDT);                //Fills the table with data from the database.
            m_sqlConnection.Close();                    //closes the connection with database.
            return roadInfoDT;
        }

        /// <summary>
        /// This function updates the table "RoadInformation," randomly.
        /// </summary>
        public void UpdateData()
        {
            string updateString = "";
            for (int i = 1; i <= 10; i++)
            {
                updateString = "Update RoadInformation Set Status='" + this.GetRandomStatus() + "', Timestamp='" + DateTime.Now + "' where Id = " + i;
                SqlConnection sqlConnection = new SqlConnection(m_connectionString);        // Instantiate sql connection object
                SqlCommand sqlCommand = new SqlCommand(updateString, sqlConnection);        // Instantiate sql command object, which is used for executing query.
                try
                {
                    //if (m_sqlConnection.State== ConnectionState.Closed)
                    //{
                    sqlConnection.Open();

                    //}
                    sqlCommand.ExecuteNonQuery();            // execute the update query.

                    //if (m_sqlConnection.State == ConnectionState.Open)
                    //{
                    sqlConnection.Close();

                    //}

                }
                catch (Exception ex)
                {
                    throw ex;
                }

            }

        }

        /// <summary>
        ///  This function returns a status of the road randomly.
        /// </summary>
        /// <returns></returns>
        private string GetRandomStatus()
        {
            Random rand = new Random();
            string status = "";

            switch (rand.Next(4))                // this will generate a random number between 0 and 4
            {
                case 0:
                    status = Status.Normal.ToString();            //sets the status
                    break;
                case 1:
                    status = Status.Slow.ToString();            //sets the status
                    break;
                case 2:
                    status = Status.Congested.ToString();        //sets the status
                    break;
                case 3:
                    status = Status.Accident.ToString();        //sets the status
                    break;
                default:
                    break;
            }
            return status;

        }
    }

    /// <summary>
    ///This enum is used for defining the status of the road.
    /// </summary>
    public enum Status
    {
        Normal,
        Slow,
        Congested,
        Accident,

    }
}

Comments

Popular posts from this blog

html to Word Document Converter using Open XML SDK

How to: Get Top n Rows of DataView in C# asp.net