Click here to Skip to main content
15,885,914 members
Please Sign up or sign in to vote.
3.00/5 (1 vote)
See more:
I have managed to create a Server/Client chat system, where the client sends a message to the server and the the server sends the message to all the clients.

I want to extend this so that the Server compares the messages and then sends a message to the client.

For Example: If client 1 sends 10 and client 2 sends 20 the server will compare these and the server will send a message saying 20 is more than 10.

Is this possible to do? And if so how?


Server Code:

namespace Server
{
    public partial class Form1 : Form
    {

        private const int m_iMaxConnections = 2;

        struct Connection_Struct    // Define a structure to hold details about a single connection
        {
            public Socket ClientSpecific_Socket;
            public bool bInUse;
        };

        Socket m_ListenSocket;
        Socket m_SendSocket;

        Connection_Struct[] m_Connection_Array = new Connection_Struct[m_iMaxConnections]; // Define an array to hold a number of connections

        System.Net.IPEndPoint m_LocalIPEndPoint;
        static int m_iNumberOfConnectedClients;
        private static System.Windows.Forms.Timer m_CommunicationActivity_Timer;

        public Form1()
        {
            InitializeComponent();

            Initialise_ConnectionArray();
            m_CommunicationActivity_Timer = new System.Windows.Forms.Timer(); // Check for communication activity on Non-Blocking sockets every 200ms
            m_CommunicationActivity_Timer.Tick += new EventHandler(OnTimedEvent_PeriodicCommunicationActivityCheck); // Set event handler method for timer
            m_CommunicationActivity_Timer.Interval = 100;  // Timer interval is 1/10 second
            m_CommunicationActivity_Timer.Enabled = false;
            string szLocalIPAddress = GetLocalIPAddress_AsString(); // Get local IP address as a default value
            txtIPAddress.Text = szLocalIPAddress;             // Place local IP address in IP address field
            txtPort.Text = "8000";  // Default port number
            m_iNumberOfConnectedClients = 0;
            txtClientNo.Text = System.Convert.ToString(m_iNumberOfConnectedClients);

            try
            {   // Create the Listen socket, for TCP use
                m_ListenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                m_ListenSocket.Blocking = false;
                m_SendSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Tcp);
            }
            catch (SocketException se)
            {   // If an exception occurs, display an error message
                MessageBox.Show(se.Message);
            }

        }


        private void Initialise_ConnectionArray()
        {
            int iIndex;
            for (iIndex = 0; iIndex < m_iMaxConnections; iIndex++)
            {
                m_Connection_Array[iIndex].bInUse = false;
            }
        }



        private void btnEnableServer_Click(object sender, EventArgs e)
        {


            // Bind to the selected port and start listening / receiving
            try
            {
                // Get the Port number from the appropriate text box
                String szPort = txtPort.Text;
                int iPort = System.Convert.ToInt16(szPort, 10);
                // Create an Endpoint that will cause the listening activity to apply to all the local node's interfaces
                m_LocalIPEndPoint = new System.Net.IPEndPoint(IPAddress.Any, iPort);
                // Bind to the local IP Address and selected port
                m_ListenSocket.Bind(m_LocalIPEndPoint);

                txtLog.Text = "Bind succeded";

                // Prevent any further changes to the port number
                txtPort.ReadOnly = true;
            }

            catch // Catch any errors
            {   // If an exception occurs, display an error message
                txtLog.Text = "Bind failed";
            }





            try
            {
                txtLog.Text = "Listening";
                m_ListenSocket.Listen(2); // Listen for connections, with a backlog / queue maximum of 2

            }
            catch (SocketException se)
            {
                // If an exception occurs, display an error message
                MessageBox.Show(se.Message);
            }
            catch // Silently handle any other exception
            {
            }



            m_CommunicationActivity_Timer.Start();  // Start the timer to perform periodic checking for connection requests   
            txtLog.Text = "Accepting (waiting for connection attempt)";
            btnEnableServer.Enabled = false;



        }




        private void OnTimedEvent_PeriodicCommunicationActivityCheck(Object myObject, EventArgs myEventArgs)
        {   // Periodic check whether a connection request is pending or a message has been received on a connected socket     

            // First, check for pending connection requests
            int iIndex;
            iIndex = GetnextAvailable_ConnectionArray_Entry(); // Find an available array entry for next connection request
            if (-1 != iIndex)
            {   // Only continue with Accept if there is an array entry available to hold the details

                try
                {
                    m_Connection_Array[iIndex].ClientSpecific_Socket = m_ListenSocket.Accept();  // Accept a connection (if pending) and assign a new socket to it (AcceptSocket)
                    // Will 'catch' if NO connection was pending, so statements below only occur when a connection WAS pending
                    m_Connection_Array[iIndex].bInUse = true;
                    m_Connection_Array[iIndex].ClientSpecific_Socket.Blocking = false;           // Make the new socket operate in non-blocking mode
                    m_iNumberOfConnectedClients++;
                    txtClientNo.Text = System.Convert.ToString(m_iNumberOfConnectedClients);
                    txtLog.Text = "A new client connected";

                    SendUpdateMesageToAllConnectedclients();
                }
                catch (SocketException se) // Handle socket-related exception
                {   // If an exception occurs, display an error message
                    if (10053 == se.ErrorCode || 10054 == se.ErrorCode) // Remote end closed the connection
                    {
                        CloseConnection(iIndex);
                    }
                    else if (10035 != se.ErrorCode)
                    {   // Ignore error messages relating to normal behaviour of non-blocking sockets
                        MessageBox.Show(se.Message);
                    }
                }
                catch // Silently handle any other exception
                {
                }
            }

            // Second, check for received messages on each connected socket
            for (iIndex = 0; iIndex < m_iMaxConnections; iIndex++)
            {
                if (true == m_Connection_Array[iIndex].bInUse)
                {
                    try
                    {
                        EndPoint localEndPoint = (EndPoint)m_LocalIPEndPoint;
                        byte[] ReceiveBuffer = new byte[1024];
                        int iReceiveByteCount;
                        iReceiveByteCount = m_Connection_Array[iIndex].ClientSpecific_Socket.ReceiveFrom(ReceiveBuffer, ref localEndPoint);

                        string szReceivedMessage;
                        if (0 < iReceiveByteCount)
                        {   // Copy the number of bytes received, from the message buffer to the text control
                            szReceivedMessage = Encoding.ASCII.GetString(ReceiveBuffer, 0, iReceiveByteCount);
                            if ("QuitConnection" == szReceivedMessage)
                            {
                                CloseConnection(iIndex);
                            }
                            else
                            {

                               txtLog.AppendText(szReceivedMessage + Environment.NewLine);


                                // Send message to each connected client.

                                //  int iIndex2;
                                for (iIndex = 0; iIndex < m_iMaxConnections; iIndex++)
                                {
                                    if (true == m_Connection_Array[iIndex].bInUse)
                                    {
                                        string szMessage;

                                        szMessage = szReceivedMessage;

                                        txtLog.Text = m_Connection_Array[m_iMaxConnections].ToString();



                                        byte[] SendMessage = System.Text.Encoding.ASCII.GetBytes(szMessage);
                                        m_Connection_Array[iIndex].ClientSpecific_Socket.Send(SendMessage, SocketFlags.None);
                                    }
                                }



                            }
                        }
                    }
                    catch (SocketException se) // Handle socket-related exception
                    {   // If an exception occurs, display an error message
                        if (10053 == se.ErrorCode || 10054 == se.ErrorCode) // Remote end closed the connection
                        {
                            CloseConnection(iIndex);
                        }
                        else if (10035 != se.ErrorCode)
                        {   // Ignore error messages relating to normal behaviour of non-blocking sockets
                            MessageBox.Show(se.Message);
                        }
                    }
                    catch // Silently handle any other exception
                    {
                    }
                }
            }
        }





        private void SendUpdateMesageToAllConnectedclients()
        {   // Send message to each connected client informing of the total number of connected clients
            int iIndex;
            for (iIndex = 0; iIndex < m_iMaxConnections; iIndex++)
            {
                if (true == m_Connection_Array[iIndex].bInUse)
                {
                    string szMessage;
                    if (1 == m_iNumberOfConnectedClients)
                    {
                        szMessage = string.Format("There is now {0} client connected", m_iNumberOfConnectedClients);
                    }
                    else
                    {
                        szMessage = string.Format("There are now {0} clients connected", m_iNumberOfConnectedClients);
                    }
                    byte[] SendMessage = System.Text.Encoding.ASCII.GetBytes(szMessage);
                    m_Connection_Array[iIndex].ClientSpecific_Socket.Send(SendMessage, SocketFlags.None);
                }
            }
        }

        private void CloseConnection(int iIndex)
        {
            try
            {
                m_Connection_Array[iIndex].bInUse = false;
                m_Connection_Array[iIndex].ClientSpecific_Socket.Shutdown(SocketShutdown.Both);
                m_Connection_Array[iIndex].ClientSpecific_Socket.Close();
                m_iNumberOfConnectedClients--;
                txtClientNo.Text = System.Convert.ToString(m_iNumberOfConnectedClients);
                txtLog.Text = "A Connection was closed";
                SendUpdateMesageToAllConnectedclients();
            }
            catch // Silently handle any exceptions
            {
            }
        }





        private void Close_And_Quit()
        {   // Close the sockets and exit the application
            try
            {
                m_ListenSocket.Close();
            }
            catch
            {
            }
            try
            {
                int iIndex;
                for (iIndex = 0; iIndex < m_iMaxConnections; iIndex++)
                {
                    m_Connection_Array[iIndex].ClientSpecific_Socket.Shutdown(SocketShutdown.Both);
                    m_Connection_Array[iIndex].ClientSpecific_Socket.Close();
                }
            }
            catch
            {
            }
            try
            {
                Close();
            }
            catch
            {
            }
        }



        public string GetLocalIPAddress_AsString()
        {
            string szHost = Dns.GetHostName();
            string szLocalIPaddress = "127.0.0.1";  // Default is local loopback address
            IPHostEntry IPHost = Dns.GetHostEntry(Dns.GetHostName());
            foreach (IPAddress IP in IPHost.AddressList)
            {
                if (IP.AddressFamily == AddressFamily.InterNetwork) // Match only the IPv4 address
                {
                    szLocalIPaddress = IP.ToString();
                    break;
                }
            }
            return szLocalIPaddress;
        }


        private int GetnextAvailable_ConnectionArray_Entry()
        {
            int iIndex;
            for (iIndex = 0; iIndex < m_iMaxConnections; iIndex++)
            {
                if (false == m_Connection_Array[iIndex].bInUse)
                {
                    return iIndex;  // Return the index value of the first not-in-use entry found
                }
            }
            return -1;      // Signal that there were no available entries
        }



    }
}



Client Code:

namespace Client
{
public partial class Form1 : Form
{

    Socket m_ClientSocket;
    System.Net.IPEndPoint m_remoteEndPoint;
    IPEndPoint m_localIPEndPoint;
    Socket m_ReceiveSocket;

    private static System.Windows.Forms.Timer m_CommunicationActivity_Timer;

    public Form1()
    {
        InitializeComponent();

        m_CommunicationActivity_Timer = new System.Windows.Forms.Timer(); // Check for communication activity on Non-Blocking sockets every 200ms
        m_CommunicationActivity_Timer.Tick += new EventHandler(OnTimedEvent_PeriodicCommunicationActivityCheck); // Set event handler method for timer
        m_CommunicationActivity_Timer.Interval = 100;  // Timer interval is 1/10 second
        m_CommunicationActivity_Timer.Enabled = false;

        string szLocalIPAddress = GetLocalIPAddress_AsString(); // Get local IP address as a default value
        txtIPAddress.Text = szLocalIPAddress;             // Place local IP address in IP address field
        txtPort.Text = "8000"; // Default port number


    }

    private void btnConnect_Click(object sender, EventArgs e)
    {



        // Connect the Socket with a remote endpoint
        try
        {
            // Create the socket, for TCP use
            m_ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            m_ClientSocket.Blocking = true; // Socket operates in Blocking mode initially
        }
        catch // Handle any exceptions
        {
            Close_Socket_and_Exit();
        }
        try
        {
            // Get the IP address from the appropriate text box
            String szIPAddress = txtIPAddress.Text;
            System.Net.IPAddress DestinationIPAddress = System.Net.IPAddress.Parse(szIPAddress);

            // Get the Port number from the appropriate text box
            String szPort = txtPort.Text;
            int iPort = System.Convert.ToInt16(szPort, 10);

            // Combine Address and Port to create an Endpoint
            m_remoteEndPoint = new System.Net.IPEndPoint(DestinationIPAddress, iPort);

            m_ClientSocket.Connect(m_remoteEndPoint);
            m_ClientSocket.Blocking = false;    // Socket is now switched to Non-Blocking mode for send/ receive activities
            txtLog.Text = "Connected";


            m_CommunicationActivity_Timer.Start();  // Start the timer to perform periodic checking for received messages   
        }
        catch // Catch all exceptions
        {   // If an exception occurs, display an error message
            txtLog.Text = "(Connect attempt failed)\nRetry Connect";
        }







    }



    private void OnTimedEvent_PeriodicCommunicationActivityCheck(Object myObject, EventArgs myEventArgs)
    {   // Periodic check whether a message has been received    
        try
        {
            EndPoint RemoteEndPoint = (EndPoint)m_remoteEndPoint;
            byte[] ReceiveBuffer = new byte[1024];
            int iReceiveByteCount;
            iReceiveByteCount = m_ClientSocket.ReceiveFrom(ReceiveBuffer, ref RemoteEndPoint);

            string szReceivedMessage;
            if (0 < iReceiveByteCount)
            {   // Copy the number of bytes received, from the message buffer to the text control
                szReceivedMessage = Encoding.ASCII.GetString(ReceiveBuffer, 0, iReceiveByteCount);

               txtResult.Text = szReceivedMessage;
            }
        }
        catch // Silently handle any exceptions
        {
        }
    }

    private void Close_Socket_and_Exit()
    {
        try
        {
            m_ClientSocket.Shutdown(SocketShutdown.Both);
        }
        catch // Silently handle any exceptions
        {
        }
        try
        {
            m_ClientSocket.Close();
        }
        catch // Silently handle any exceptions
        {
        }
        this.Close();
    }

    private void btnDisconnect_Click(object sender, EventArgs e)
    {


        try
        {
            String szData = "QuitConnection"; // Special code to signal 'close connection' to the server
            // This ensures that the server is aware the Client wants to close the connection
            // (TCP should otherwise automatically detect disconnection, but this approach ensures a clean disconnect)
            byte[] byData = System.Text.Encoding.ASCII.GetBytes(szData);
            m_ClientSocket.Send(byData, SocketFlags.None);
            m_ClientSocket.Shutdown(SocketShutdown.Both);
            m_ClientSocket.Close();


            btnConnect.Text = "Connect";
            txtResult.Text = "";

        }
        catch // Silently handle any exceptions
        {
        }






    }



    private string GetLocalIPAddress_AsString()
    {
        string szHost = Dns.GetHostName();
        string szLocalIPaddress = "127.0.0.1";  // Default is local loopback address
        IPHostEntry IPHost = Dns.GetHostEntry(Dns.GetHostName());
        foreach (IPAddress IP in IPHost.AddressList)
        {
            if (IP.AddressFamily == AddressFamily.InterNetwork) // Match only the IPv4 address
            {
                szLocalIPaddress = IP.ToString();
                break;
            }
        } return szLocalIPaddress;
    }

}
}



Thanks
Posted

1 solution

hmmm simply use signalr here's a full example for you Asp.Net SignalR Chat Room[^]
best of luck
 
Share this answer
 
Comments
WA_coder 20-Mar-14 15:31pm    
Thanks but that doesn't solve my problem or guide me in the correct path.
Hassue Rana 20-Mar-14 15:40pm    
in that example of signalr you can find the ConnectedUsers that is a list of connected users
and also theres list of messages sent by clients you can easily compare on server.
WA_coder 20-Mar-14 15:56pm    
Oh OK. Do you know how I could implement that into my code?
Thanks
Hassue Rana 20-Mar-14 16:04pm    
in that example you'll find everything u need just download code and run in visual studio... even if you use signalr you can use any kind of client like java, dos , winform , wpf etc... and also you can find signalr self hsot server examples in example if your project is not in asp.net then find signalr example appropriate to your project
Hassue Rana 20-Mar-14 16:06pm    
and also remember sockets doesn't works behind the firewall but signalr works because it uses http

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900