Friday, July 6, 2012

Building a chat application - TCP

We all know that TCP (Transmission Control Protocol) is a connected architecture.
So we need a server and client.
The server receive all the incoming tcp packets and send to all the clients connected to the sever.

We need to create a console application for the sever and a windows application for the client.



The codes for server is-----


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

namespace ChatServer
{
    class Program
    {
        public static Hashtable clientsList = new Hashtable();

        static void Main(string[] args)
        {
            string name=Dns.GetHostName();
            string dummy = null;
            TcpClient c;
            IPAddress[] address = Dns.GetHostEntry(name).AddressList;
            TcpListener serverSocket = new TcpListener(address[1], 8889);// Server ip address.
//This should be given written in the client code
            TcpClient clientSocket = default(TcpClient);
            int counter = 0;

            serverSocket.Start();
            Console.WriteLine("Chat Server Started ....");
            counter = 0;
            while ((true))
            {
                counter += 1;
                clientSocket = serverSocket.AcceptTcpClient();

                byte[] bytesFrom = new byte[10025];
                string dataFromClient = null;

                NetworkStream networkStream = clientSocket.GetStream();
                networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);
                dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);
                dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));

                if (!clientsList.ContainsKey(dataFromClient))
                {
                    clientsList.Add(dataFromClient, clientSocket);

                    broadcast(dataFromClient + " Joined the room...", dataFromClient, false, out dummy, out c);
                    BroadcastClientList();
                    Console.WriteLine(dataFromClient + " Joined chat room ");
                    handleClinet client = new handleClinet();
                    client.startClient(clientSocket, dataFromClient, clientsList);
                }
                else
                {
                    byte[] bytes = Encoding.ASCII.GetBytes("Exists%");
                    networkStream.Write(bytes, 0, bytes.Length);
                }
            }

            clientSocket.Close();
            serverSocket.Stop();
            Console.WriteLine("exit");
            Console.ReadLine();
        }

        public static void broadcast(string msg, string uName, bool flag, out string name, out TcpClient client)
        {

            client = new TcpClient();
            name = null;
            IAsyncResult re;
            foreach (DictionaryEntry Item in clientsList)
            {
                try
                {
                    TcpClient broadcastSocket;
                    broadcastSocket = (TcpClient)Item.Value;

                    NetworkStream broadcastStream = broadcastSocket.GetStream();
                    Byte[] broadcastBytes = null;
                    if (msg == "logged out...")
                    {
                        client = (TcpClient)Item.Value;
                        broadcastBytes = Encoding.ASCII.GetBytes(uName + " >> " + msg);
                        name = uName;
                    }
                    else if (flag == true)
                    {
                        broadcastBytes = Encoding.ASCII.GetBytes(uName + " says >> " + msg);
                    }
                    else
                    {
                        broadcastBytes = Encoding.ASCII.GetBytes(msg);
                    }


                    broadcastStream.Write(broadcastBytes, 0, broadcastBytes.Length);
                    broadcastStream.Flush();                   
                }
                catch
                {
                    continue;
                }
            }
          
        }

        public static void BroadcastClientList()
        {
            string nameList = string.Empty;
            nameList = getAllUsers();

            foreach (DictionaryEntry item in clientsList)
            {
                TcpClient client = new TcpClient();
                client = (TcpClient)item.Value;

                NetworkStream stream = client.GetStream();
                Byte[] byteStream = System.Text.Encoding.ASCII.GetBytes(nameList);

                stream.Write(byteStream, 0, byteStream.Length);

            }
          
        }

        public static string getAllUsers()
        {
            string name=string.Empty;

            foreach (DictionaryEntry item in clientsList)
            {
                if (string.IsNullOrEmpty(name))
                {
                    name = "/#List/" + item.Key.ToString() + "&^";
                }
                else
                {
                    name = name + item.Key.ToString() + "&^";
                }
            }

            return name;
        }
    }//end Main class


    public class handleClinet
    {
        TcpClient clientSocket;
        string clNo;
        Hashtable clientsList;
        Thread ctThread;
      
        public void startClient(TcpClient inClientSocket, string clineNo, Hashtable cList)
        {

            this.clientSocket = inClientSocket;
            this.clNo = clineNo;
            this.clientsList = cList;
            ctThread = new Thread(doChat);
            ctThread.Start();
         
           
        }

        private void doChat()
        {
          
                byte[] bytesFrom = new byte[10025];
                string dataFromClient = null;
                string logoutUsername = null;
                TcpClient logoutClient;

                while ((true))
                {
                    try
                    {
                        if (clientSocket.Client.Connected)
                        {
                         
                            NetworkStream networkStream = clientSocket.GetStream();
                            networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);
                            dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);
                            dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));
                            Console.WriteLine(clNo + " : " + dataFromClient);

                            Program.broadcast(dataFromClient, clNo, true, out logoutUsername, out logoutClient);

                            if (logoutUsername != null)
                            {
                                clientsList.Remove(logoutUsername);
                                Program.BroadcastClientList();
                              
                                break;
                            }

                            if (clientsList.Count == 0)
                                break;
                        }
                       
                    }

                    catch (Exception ex)
                    {
                        //Console.WriteLine(ex.ToString());
                    }

                }//end while  
                Thread.CurrentThread.Abort();
        }//end doChat
    } //end class handleClinet
}
//----------------------------------------------------------------------------------------------
 

//The Codes for the client is
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Net.Sockets;

namespace ChatClient
{
    public partial class Messenger : Form
    {

        public  TcpClient clientSocket = new TcpClient();
        public  NetworkStream serverStream = default(NetworkStream);
        public  string readData = null;
        Chat chat = new Chat();
        Thread ctThread;
        List<user> users;      

        public Messenger()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            SendChat();          
        }

        private void SendChat()
        {
            try
            {
                if (!string.IsNullOrEmpty(txtMessage.Text))
                {
                    byte[] outStream = System.Text.Encoding.ASCII.GetBytes(txtMessage.Text + "$");
                    serverStream.Write(outStream, 0, outStream.Length);
                    serverStream.Flush();
                    txtMessage.Clear();                 
                    txtMessage.Focus();                  
                }
            }
            catch
            {
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            EnterChat();
        }

        private void EnterChat()
        {
            try
            {
                if (!string.IsNullOrEmpty(txtUserName.Text))
                {                  

                    readData = "Conected to Chat Server ...";
                    msg();

                    if (clientSocket.Connected)
                    {
                        clientSocket.Close();
                        clientSocket = new TcpClient();
                    }

                    clientSocket.Connect("192.168.10.001", 8889);// enter the server ip address, by // //debugging the server program first.
                    serverStream = clientSocket.GetStream();

                    byte[] outStream = System.Text.Encoding.ASCII.GetBytes(txtUserName.Text + "$");
                    serverStream.Write(outStream, 0, outStream.Length);
                    serverStream.Flush();

                    ctThread = new Thread(getMessage);
                    ctThread.Start();

                    button2.Enabled = false;
                    button2.Hide();
                    btnExit.Hide();
                    btnSend.Show();
                    pictureBox1.Hide();
                    label1.Hide();
                    txtUserName.Hide();
                    txtMessengerWindow.Show();
                    txtMessage.Show();
                    btnLogOut.Show();
                    txtMessage.Focus();
                    btnMinimize.Visible = true;
                    dgridUsers.Visible = true;
                }
            }
            catch(Exception e)
            {
                MessageBox.Show("Chat Server is not started", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);               
                Application.Exit();
            }
        }

        public void msg()
        {
            if (this.InvokeRequired)
                this.Invoke(new MethodInvoker(msg));
            else
            {
                txtMessengerWindow.Text = txtMessengerWindow.Text + Environment.NewLine + readData;
                txtMessengerWindow.SelectionStart = txtMessengerWindow.Text.Length;
                txtMessengerWindow.ScrollToCaret();
                txtMessengerWindow.Refresh();
            }
        }

        public void getMessage()
        {
            try
            {
                while (true)
                {
                    serverStream = clientSocket.GetStream();
                    int buffSize = 0;
                    byte[] inStream = new byte[10025];

                    if (clientSocket.Client.Connected)
                    {
                        buffSize = clientSocket.ReceiveBufferSize;
                        serverStream.Read(inStream, 0, buffSize);
                        string returndata = System.Text.Encoding.ASCII.GetString(inStream);

                        returndata = returndata.Replace("\0", "");

                        if (!string.IsNullOrEmpty(returndata))
                        {
                            if (returndata.StartsWith("Exists"))
                            {
                                UserExists();
                            }
                            else if (returndata.StartsWith("/#List/"))
                            {
                                BindData(returndata);
                            }
                            else if (returndata.Contains("/#List/"))
                            {
                                int start = returndata.IndexOf("/#List/");
                                int length = returndata.LastIndexOf("&^");
                                length -= start;
                                string msg = returndata.Substring(0, start);
                                string list = returndata.Substring(start, length);
                                BindData(list);
                                SendMessage(msg);
                            }
                            else
                            {
                                SendMessage(returndata);

                            }
                        }
                        else
                        {
                            try
                            {
                                DialogResult r = MessageBox.Show("Unable to connect to the chat server, Please try after sometimes...", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                if (r == DialogResult.OK)
                                {                                  
                                    Application.Exit();
                                }
                            }
                            catch
                            {
                                Application.ExitThread();
                                Application.Exit();
                            }
                        }
                    }
                }
            }
            catch
            {
                DialogResult r = MessageBox.Show("Unable to connect to the chat server, Please try after sometimes...", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                if (r == DialogResult.OK)
                {                  
                    Application.Exit();
                }
            }
        }

        private void SendMessage(string returndata)
        {
            if (InvokeRequired)
                this.Invoke(new MethodInvoker(delegate() { SendMessage(returndata); }));

            else
            {
                readData = "" + returndata;

                if (this.WindowState == FormWindowState.Minimized)
                {
                    notify.BalloonTipTitle = "New Chat Recevied";
                    notify.BalloonTipText = returndata;
                    notify.ShowBalloonTip(500);
                    msg();
                }
                else
                {
                    msg();
                }
            }
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            this.Close();
            Application.Exit();
        }

        private void BindData(string returndata)
        {
            if (InvokeRequired)
                this.Invoke(new MethodInvoker(delegate() { BindData(returndata); }));
            else
            {
                returndata = returndata.Replace("/#List/", "");
                returndata = returndata.Replace("\0", "");
                string[] userList = returndata.Split(new string[] { "&^" }, StringSplitOptions.None);
                users = new List<user>();

                for (int i = 0; i < userList.Length; i++)
                {
                    user u = new user();
                    u.name = userList[i];
                    users.Add(u);
                }

                dgridUsers.DataSource = users;
            }
        }
        private void btnLogOut_Click(object sender, EventArgs e)
        {
            try
            {
                byte[] outstream = System.Text.Encoding.ASCII.GetBytes("logged out...$");
                serverStream.Write(outstream, 0, outstream.Length);
                serverStream.Flush();
                ctThread.Abort();
               
            }
            catch
            {
            }

            Application.Exit();
        }

        private void txtUserName_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == Convert.ToChar(Keys.Enter))
            {
                EnterChat();
            }
        }

        private void txtMessage_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == Convert.ToChar(Keys.Enter))
            {
                SendChat();
            }
        }

        private void UserExists()
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new MethodInvoker(UserExists));
            }
            else
            {
                button2.Show();
                btnExit.Show();
                btnSend.Hide();
                pictureBox1.Show();
                label1.Show();
                txtUserName.Show();
                txtMessengerWindow.Clear();
                txtMessengerWindow.Hide();
                txtMessage.Hide();
                btnLogOut.Hide();
                button2.Enabled = true;
                txtMessage.Clear();
                txtUserName.Clear();
                txtUserName.Focus();
                btnMinimize.Visible = false;
                dgridUsers.Visible = false;
                DialogResult r= MessageBox.Show("Username Exists, Please choose another...", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);

              
                if (r == DialogResult.OK)
                {
                    this.Show();
                }
            }
        }

        private void btnMinimize_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
            notify.BalloonTipTitle = "Chat Client";
            notify.BalloonTipText = "Chat client is minimized. The incoming chats will be displayed as bubbles. You can either click the bubble or on the notify icon to resume normal chat...";
            notify.ShowBalloonTip(500);
            this.ShowInTaskbar = false;
        }

        private void notify_BalloonTipClicked(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Normal;
            this.ShowInTaskbar = true;
            txtMessage.Focus();
        }

        private void notify_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Normal;
            this.ShowInTaskbar = true;
            txtMessage.Focus();
        }

        private void notify_MouseMove(object sender, MouseEventArgs e)
        {

            notify.BalloonTipTitle = "Chat Client";
            notify.BalloonTipText = "Chat client is minimized. The incoming chats will be displayed as bubbles. You can either click the bubble or on the notify icon to resume normal chat...";
            notify.ShowBalloonTip(500);

        }

        private void Messenger_SizeChanged(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                notify.BalloonTipTitle = "Chat Client";
                notify.BalloonTipText = "Chat client is minimized. The incoming chats will be displayed as bubbles. You can either click the bubble or on the notify icon to resume normal chat...";
                notify.ShowBalloonTip(500);
                this.ShowInTaskbar = false;
            }
        }

        private void txtMessengerWindow_KeyDown(object sender, KeyEventArgs e)
        {
            e.SuppressKeyPress = true;
        }

        private void dgridUsers_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            int rowIndex = e.RowIndex;

            if (rowIndex != -1)
            {
                string name = dgridUsers.Rows[rowIndex].Cells[0].Value.ToString();

            }      
           
        }
              
    }
}

public class user
{
    public string name
    {
        get;
        set;
    }
//The article is subjected to copyright.
}


No comments:

Post a Comment