Click here to Skip to main content
15,884,472 members
Articles / Programming Languages / C#

Simple Messenger - A C# MSN Messenger-like Chat Application

Rate me:
Please Sign up or sign in to vote.
4.25/5 (24 votes)
22 Apr 2009CPOL3 min read 152.1K   18.4K   122   16
This is a MSN Messenger like chat application using C# with TCP/IP socket programming.
SimpleMessenger.JPG

SimpleMessenger_About.JPG

Introduction

This is a simple MSN Messenger like chat application using socket programming. It allows the users to send and receive messages by running two Simple Messengers.
You can read this article from my blog: http://hantou.blogspot.com/.

There are two specific features other than the regular MSN Messenger:

  1. 'Hex'
    • TRUE: The data will be displayed in Hex format.
    • FALSE: The data will be displayed in regular text.
  2. 'No print on receiving'
    • TRUE: The received data will not be printed on the textbox.
    • FALSE: The received data will be printed on the textbox.

Background

One day when I was working on socket programming, I needed to monitor data transmission. Although Visual Studio already has a debugger for the user to monitor the data, I still needed a third application to cache the data and take a look at it. This comes with the idea for the Simple Messenger. You can use this program as a chat application when you run two simple Messengers. If you connect your computer to a device, another software, a web application, etc., you will be able to send/receive data via one Simple Messenger application. In my case, I just connect my computer to a device which has Ethernet connection and I need to monitor the data sent by the device during the run time. The main purpose of this article here is to share this program with you regarding socket programming and multiple threads.

KeyValuePair

A helper class wraps a Socket and a byte array.

C#
public class KeyValuePair
{
    public Socket socket;
    public byte[] dataBuffer = new byte[1];
} 

Overview

There are two main classes named Server.cs and Client.cs standing for Server mode and Client mode respectively.  Note, the scenario is that only one server and one client are connected.  This means that if you try to open one server and multiple clients then I cannot promise anything. The one-to-many case is not implemented and this is beyond the main issue that is being discussed here.

Connection

The connection is slightly different between the Server Mode and the Client Mode.

First look at the Server Mode:

C#
public void Connect(string ipAddr, string port)
{
    server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    IPEndPoint ipLocal = new IPEndPoint(IPAddress.Any, Convert.ToInt32(port));
    server.Bind(ipLocal);//bind to the local IP Address...
    server.Listen(5);//start listening...

    // create the call back for any client connections...
    server.BeginAccept(new AsyncCallback(OnClientConnect), null);
}

The server needs to watch for the connection to see if there is any client trying to connect to it.

C#
public void OnClientConnect(IAsyncResult asyn)
{
    try
    {
        if (server != null)
        {
            tempSocket = server.EndAccept(asyn);
            WaitForData(tempSocket);
            server.BeginAccept(new AsyncCallback(OnClientConnect), null);
        }
    }
    /* ... */
} 

Before the server socket receives any data, we must prepare for it ahead. Here the KeyValuePair object is imported as a parameter.

C#
public void WaitForData(Socket soc)
{
    try
    {
        if (asyncCallBack == null)
            asyncCallBack = new AsyncCallback(OnDataReceived);

        KeyValuePair aKeyValuePair = new KeyValuePair();
        aKeyValuePair.socket = soc;

        // now start to listen for incoming data...
        aKeyValuePair.dataBuffer = new byte[soc.ReceiveBufferSize];
        soc.BeginReceive(aKeyValuePair.dataBuffer, 0, aKeyValuePair.dataBuffer.Length,
                     SocketFlags.None, asyncCallBack, aKeyValuePair);
    }
    /* ... */
} 

Now look at the Client Mode:

C#
public void Connect(string ipAddr, string port)
{
    client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    IPEndPoint ipe = new IPEndPoint(IPAddress.Parse(ipAddr), Convert.ToInt32(port));
    client.Connect(ipe);

    clientListener = new Thread(OnDataReceived);
    isEndClientListener = false;
    clientListener.Start();
}
ServerClient.JPG

Data Receive

Since the AsyncCallback is used for the server, receiving the data will be different.

For the Server Mode

C#
KeyValuePair aKeyValuePair = (KeyValuePair)asyn.AsyncState;
//end receive...
int iRx = 0;
iRx = aKeyValuePair.socket.EndReceive(asyn);
if (iRx != 0)
{
    byte[] recv = aKeyValuePair.dataBuffer;
}

For the Client Mode

C#
byte[] recv = new byte[client.ReceiveBufferSize];  //you can define your own size
int iRx = client.Receive(recv );
if (iRx != 0)
{
    //recv should contain the received data.
}

Data Send

Sending the data is as easy as calling the Send() method that comes with the Socket. E.g.

C#
soc.Send(dataBytes);//'soc' could either be the server or the client

Error Handling

In Server's receive block, you might want to handle the SocketException with ErrorCode == 10054. This error code indicates the connection reset for peers. Refer to MSDN.

C#
if (e.ErrorCode == 10054)//Connection reset, 
		// <a>http://msdn.microsoft.com/en-us/library/ms740668(VS.85).aspx</a>
{
    /* ... */
}

Points of Interest

Every time I used the MSN Messenger to chat with my friends, I was worried if my conversation would be recorded by 'MSN'. Now I'm happy and 'safe' to use my own chat application to chat with my friends, er... within a local network. However, the main benefit of this program is that I learned how to play with the Ethernet and sockets. I hope this will benefit you as well.

For more information about me, please visit my blog: hantou.blogspot.com.

History

  • 2nd July, 2008 - First version
  • 16th April, 2009 - Updated article downloads and images
  • 20th April, 2009 - Updated article

License

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


Written By
Software Developer BTI
Canada Canada
My blog: Hantou Studio【 hantou.blogspot.com 】
________________________________________________

Comments and Discussions

 
QuestionSo Use full...Thanks Pin
Member 106848013-Sep-17 22:07
Member 106848013-Sep-17 22:07 
QuestionTHANKS! Pin
Member 1305087110-Mar-17 3:41
Member 1305087110-Mar-17 3:41 
GeneralMy vote of 5 Pin
janaka45951-Jul-13 18:53
janaka45951-Jul-13 18:53 
QuestionChat Application Pin
janaka45951-Jul-13 18:53
janaka45951-Jul-13 18:53 
GeneralMy vote of 2 Pin
MG-develop14-Jun-13 15:10
MG-develop14-Jun-13 15:10 
GeneralMy vote of 5 Pin
Peter Hawke29-Dec-11 11:43
Peter Hawke29-Dec-11 11:43 
Questionabout tcplistener and tcpclient Pin
rebulanyum14-Jun-09 2:37
rebulanyum14-Jun-09 2:37 
AnswerRe: about tcplistener and tcpclient Pin
Hantou16-Jun-09 16:59
Hantou16-Jun-09 16:59 
Generalnot working for other computers within local network Pin
harikrishna21017-Nov-08 18:30
harikrishna21017-Nov-08 18:30 
GeneralRe: not working for other computers within local network [modified] Pin
Hantou18-Nov-08 5:09
Hantou18-Nov-08 5:09 
GeneralRe: not working for other computers within local network Pin
harikrishna21018-Nov-08 22:30
harikrishna21018-Nov-08 22:30 
GeneralRe: not working for other computers within local network Pin
Hantou20-Nov-08 7:35
Hantou20-Nov-08 7:35 
GeneralRe: not working for other computers within local network [modified] Pin
Hantou16-Apr-09 10:14
Hantou16-Apr-09 10:14 
GeneralRe: not working for other computers within local network Pin
wael.sidani19-Apr-10 23:43
wael.sidani19-Apr-10 23:43 
GeneralThreading [modified] Pin
Taner Riffat10-Jul-08 14:41
Taner Riffat10-Jul-08 14:41 
GeneralRe: Threading Pin
Hantou25-Aug-08 10:15
Hantou25-Aug-08 10:15 

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.