Click here to Skip to main content
15,867,835 members
Articles / Desktop Programming / Windows Forms

Creating a Client - Server app - Making a Chat

Rate me:
Please Sign up or sign in to vote.
4.77/5 (10 votes)
16 Nov 2009CPOL3 min read 56K   3.6K   43   16
Making a typical client - server chat application

Introduction

This article shows how we can create a typical client / server application, in this case, a chat.

Main chat's form

This project is divided by two parts, two solutions.

On the one hand, we have the server solution. This is a Windows Service Project. If we want to use this app, we must install first in order to join with other services on our computer. To do that, it must be installed with the installutil.exe tool.
The sentence is as follows:

installutil.exe [PATH]\svcChat.exe

In case we want to uninstall the service, we must use the following:

installutil.exe /u [PATH]\svcChat.exe 

The installer of this service is configured to start manually. If you want that service to start automatically, change the property on its constructor. You can do the same with the Service Account property.

On the other hand, we have a simple chat app made as a Windows Form Project.

Background

There are some actions used to communicate between the server and the client:

  1. #NICK#
    This action is used when client requests a change of his nickname.
  2. #JOIN#
    This action is used when client tries to join to the chat.
  3. #MSG#
    This action is used by client and server to send a message.
  4. #BYE#
    This action is used by client and server to notify that the connection will be closed.
  5. #USERLIST#
    This action is used by the server to notify the complete list of nicknames that are currently connected.
  6. #NOTNICKNAME#
    This action is used by the server to notify that the name that it is trying to change is not available.

Using the Code

This is the interesting part.

Server

The server app has two main classes: Connection and ConHandler.
Connection contains all properties and methods in order to communicate with the client, whilst ConHanlder handles all the connections that are in use. You can set the service's port number, editing the configuration file.

Also, there is a class called Logger. You can configure it through the configuration file, in order to debug the application. You just must set the file path where the service ought to write all content about its trace.

When the service starts, it throws a thread in order to listen to a new connection request. When a new connection is established, it is put into the collection of connections, and the thread throws a delegate for listening to messages from the client.

Listening to New Connections

C#
private void AcceptingSockets()
{
    try
    {
        while (true)
        {
            Socket socket = this.tcpListener.AcceptSocket();
            Connection con = new Connection(socket);
            this.connections.Add(con);
            ListenDelegate lDel = this.Recieve;
            AsyncCallback lCallBack = new AsyncCallback(this.ListenCallBack);
            lDel.BeginInvoke(con, ListenCallBack, null);
        }
    }
    catch { }
}

Receiving Data from the Client

C#
private void Recieve(Connection _con)
{
    while (_con.IsConnected)
    {
        try
        {
            string msg = _con.ReadLine();
            this.DataHandler(msg, ref _con);
            if (this.log != null)
                this.log.WriteLine(_con.NickName + ": " + msg);
        }
        catch (Exception ex)
        {
            if (this.log != null)
                this.log.WriteLine("ERROR: " + ex.Message);
        }
    }

    this.RemoveConnection(_con);
}

Once data from the client has been received, it is handled by its corresponding method.

Handling Data

C#
private void DataHandler(string _data, ref Connection _con)
{
    string[] array = _data.Split(' ');
    if (array.Length > 0)
    {
        switch (array[0])
        {
            case "#NICK#":
            case "#JOIN#":
                string nickName = array[1];
                if (!this.ExistsNickname(nickName))
                {
                    this.AddOrChangeNick(nickName, ref _con);
                    this.SendUserListToEveryBody();
                }
                else
                {
                    this.SendMessage("#NOTNICKNAME# " + nickName, _con);
                }
                break;
                
            case "#MSG#":
                this.SendMsgToEveryBody(_data, _con.NickName);
                break;
                
            case "#BYE#":
                _con.Dispose();
                this.RemoveConnection(_con);
                this.SendUserListToEveryBody();
                break;
        }
    }
}

Client

This is a simple client app.
The main class is Connection. It provides all necessary methods and properties in order to establish a connection with the server and write and receive data.
Through the connection's form, we can establish a connection with the server, indicating the server's IP address, the server's port number and the nickname that we wish to use.
When the connection is established, the app throws a thread in order to listen to all messages from the server and be handled by its corresponding method.

Connection settings form

Connecting with the Server

C#
public bool Connect()
{
    try
    {
        this.tcpClient = new TcpClient(this.serverIp, this.portConnection);
        if (this.tcpClient.Connected)
        {
            this.netStream = this.tcpClient.GetStream();
            this.streamWriter = new System.IO.StreamWriter(this.netStream);
            this.streamReader = new System.IO.StreamReader(this.netStream);
        }
    }
    catch (Exception ex)
    {
        throw new Exception(ex.Message);
    }
    
    return this.IsConnected;
}

The other option that we have available is the possibility of changing our nickname using the nickname's form.

Changing nickname

Of course, if you wish to add more features, you can modify the project by adding new methods on the server service and the client app.

License

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


Written By
Software Developer (Senior)
Spain Spain
http://www.linkedin.com/in/gerard-castello-viader
https://github.com/gcastellov

Comments and Discussions

 
Questioninstallutil.exe [PATH]\svcChat.exe what i write in path Pin
1604198429-Nov-12 2:40
1604198429-Nov-12 2:40 
AnswerRe: installutil.exe [PATH]\svcChat.exe what i write in path Pin
Gerard Castelló Viader29-Nov-12 21:33
Gerard Castelló Viader29-Nov-12 21:33 
QuestionHey, the server refuses to start up! Pin
Stutcov11-Jul-12 13:05
Stutcov11-Jul-12 13:05 
AnswerRe: Hey, the server refuses to start up! Pin
Gerard Castelló Viader14-Jul-12 9:07
Gerard Castelló Viader14-Jul-12 9:07 
QuestionSend Message to somebody Pin
w78gj28-Nov-10 16:19
w78gj28-Nov-10 16:19 
QuestionsvcChat.exe WebServise Pin
Member 83208620-Apr-10 23:21
Member 83208620-Apr-10 23:21 
AnswerRe: svcChat.exe WebServise Pin
Gerard Castelló Viader21-Apr-10 8:24
Gerard Castelló Viader21-Apr-10 8:24 
GeneralRe: svcChat.exe WebServise Pin
Member 83208622-Apr-10 5:26
Member 83208622-Apr-10 5:26 
GeneralRe: svcChat.exe WebServise Pin
Gerard Castelló Viader23-Apr-10 4:19
Gerard Castelló Viader23-Apr-10 4:19 
Hi mate!!

There is no problem that both applications work in a local environment. Actually I tested these applications in a local machine.

So, be sure the service is listening to the port number 8889. You can use the command netstat to be sure about it.

Some antivirus or firewalls block some services when those are trying to listen to any port and any permission has been granted. Be sure that this is not the case.

Let me know whether it has been useful or not.
GeneralRe: svcChat.exe WebServise Pin
Member 83208626-Apr-10 20:34
Member 83208626-Apr-10 20:34 
GeneralRe: svcChat.exe WebServise Pin
Member 83208626-Apr-10 22:14
Member 83208626-Apr-10 22:14 
GeneralRe: svcChat.exe WebServise Pin
Gerard Castelló Viader27-Apr-10 1:14
Gerard Castelló Viader27-Apr-10 1:14 
AnswerRe: svcChat.exe WebServise Pin
Member 83208627-Apr-10 4:16
Member 83208627-Apr-10 4:16 
GeneralThanks Pin
George Swan16-Nov-09 20:14
mveGeorge Swan16-Nov-09 20:14 
GeneralTry and Catch Pin
morisson_c16-Nov-09 20:12
morisson_c16-Nov-09 20:12 
GeneralRe: Try and Catch Pin
Gerard Castelló Viader17-Nov-09 2:29
Gerard Castelló Viader17-Nov-09 2:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.