Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

chat program udp

1.94/5 (9 votes)
9 Jun 2008Ms-PL12 min read 1   2.9K  
p2p lan chat program

Introduction

This Project is making a chat Project which is work with P2P systems for LAN. General chat programs work with connection oriented protocols and these programs need clients, minimum one server . In companies many of them use one server machine if it is wanted chat programs the server could run in this server but home or small companies generally does not have and need a server machine .

In my program I try to make a P2P chat program for this small companies, homeusers which don’t have any server machine. For making this connection, P2P system, I use UDP (Unit Data Packet) protocol broadcasting system,multithreading architecture,polymorphism,MDI(Multiple-Document-Interface) in my program .

I use C# programing language and 3.5 .Net Framework .C# offers enhanced object-oriented programming features.

Using the Code

Multi Threading

C# contains many innovative features, one of the most exciting is its built in support for multithreaded programming.

A multithreaded program contains two or more parts that can run concurrently. Each part of such a program is called a thread, and each thread defines a separate path of execution. Thus, multithreading is a specialized form of multitasking.

Multithreaded applications provide the illusion that numerous activities are happening at more or less the same time. But the reality is the CPU uses something known as “Time Slice” to switch between different threads.

When a program creates a Thread, the program specifies the Thread’s ThreadStart delegate as the argument to the Thread constructor. The ThreadStart delegate must be a method returns void and takes no arguments.

KeepAlive = new Thread(new ThreadStart(SendIHere));

In this constructor thread name is KeepAlive and it delegate SendIHere method which returns void. This thread sends every computer in LAN “I am still online don’t delete me in your list”.

In this state your thread become ready to star but ıt isn’t working. This state is called Ready or Runnable state up to you call Start. After you call start your thread start working until your Sleep or Abort calling.

KeepAlive.Start();// start to thread until sleep or abort calling

A thread can suspend itself by calling Sleep(). Takes parameter in form of milliseconds. We can use a special timeout 0 to terminate the current time slice and give other thread a chance to use CPU time.

Thread.Sleep(60000); //this mean wait 60000 ms then work again

There are five different threads run in my program. I don’t meet any using these threads because none of them use same variables. For using same variables different thread c# also provide monitor class.

Thread threadudp:

This thread work in mainwindow.cs. This thread always works,its job is waiting packet from network. This thread listens 5000th port. When any packet received make action. This thread send WaitForPackets function to constructor.

Thread deleteactiviy:

This thread work in useronlinepanel.cs file. This thread sleep time 60000 ms.This thread work for deleting users activities which haven’t sent any message in 60000 miliseconds and make activities zero. Firstly check users’ activities if it is not zero make it zero. if it is, then delete them from onlineuserlist . This thread send DeleteActvity function to constructor.

Thread KeepAlive:

This thread in mainwindow.cs gile. This thread is provide communication with P2P. Broadcasting “I am online” message is sent by this thread. This thread sleep time 10000 ms.

Also message number for lampard timestamps theory.

Thread checkonline:

This thread also same in mainwindow.cs file. This thread work every 30000 milisecond .It is job cleaning online user listbox and rewrite list. Also when new user message received there is another function which is called online() write his name listbox.

Multiple Document InterFace(MDI):

Multiple document interface programs enable users to edit documents (such as PaintShop,AdopePhotoShop) . The application window of an MDI program is called the parent window . My program MDI parent window is windowmain.cs form. Although an MDI application can have many children. Publicroom and privateroom form are child of mainwindow. Furthermore,a maximum of one child window can be active at once. Child windows can not be outside of the parents.

For create MDI for,set f Form’s IsMDIContainer property is true.

this.IsMdiContainer = true;

In my project mainwindow form is parent MDI ,publicroom and privateroom forms are child form.

When mainwindow form start, users face with a textbox that want users to enter their name. If users enter their name, then publicroom form starts. The code given below shows that how publicroom starts.

publicroom = new PublicRoom(localusername);// construct publicroom send localusername

publicroom.MdiParent = this; // publicroom form is child of this (mainwindow form)

publicroom.WindowState = FormWindowState.Maximized; / /maximized child form in parent border

Privateroom form can start with two ways.First one is that it is started by desiring of the people in publicroom.In this way the “PO” header message open privateroom.However in the second way you select a name from listbox then send “PO” header messages this user.

Privateroom form has also thread which listens to 5000th port in UDP.However since we call this privateroom form from thread UDP,and privateroom has also thread.That means it is perceived thread called in other thread and this causes warning.

Synchronization

TCP/IP (Connection-Oriented) checks the connections, order of messages and whether messages arrived or not. If TCP/IP is used, we don’t need to check that whether messages arrived or not and whether people online or not..

The most difficult part of program is Synchronization. Synchronization synchronizes between messages and users. Because UDP is connectionless-oriented protocol

I add header part for every messages, also for missing messages I use lamport timestamps. Lamport timestamps was invented by Leslie Lamport a simple mechanism by which the happened-before ordering can be captured numerically. A Lamport logical clock is a monotonically incrementing software counter.

It follows some simple rules:

  1. The counter is incremented before each event is issued at the process;
  2. When a process sends a message, it includes the counter value with the message;
  3. On receiving a message a process computes the counter as the maximum between their own value and the received value and then applies rule 1 before timestamping the event as received..(2)

I use lamport timestamps in this way in my project every message has its own message number. If one is missing than receiver wants sender to send again the message. Than if its order is true write the message on the screen. When the program starts message number initializes with 100 .Because when I convert this value int to string I get three characters from this message So that destination computer separates the messages easily and checks the last arrived message number. If there are missing messages, destination computer sends last message number arrived and wants missing messages. In every message type I checked message numbers.

For updating online user list I create a thread and this thread sends I am here message every 20000 ms (computer clock time) .Moreover the thread sends I here message which includes the last message number and the private room number. Every private rooms use different port number. To block the coincidence increase the port number. The private number is the max used for opening private room cause every private room connections has different port number and in public room every user must know the last port number which is used the in public room and set their port number for next opening private room .

Message Types

I arranged the message type with respect to first character of message.

“S” Message

This message shows that whether users are online or not. In second part “S” message type stores the user last message number. Third part is that maximum port number sender used. Fourth part stores user name. SendIHere which is controlled by KeepAlive thread , function send this message every 10000 ms .

Sample:

S10514ahmet

S mean that I send service message If I am not on your list add me ,If I am already on your list change with my activity parameter to one.

“105” mean I send 5 message check with last message which you got from me.

“ahmet” is my name.

14 mean is that the maximum private number in publicroom which I heard If your privateroomnumber smaller than make 14. If you want open a private room with anybody use 15 and make port number 5015.

‘M’ Message:

This mean this is normal message you can write this message on your screen. This message type also includes the number of message which user send .

Example:

M108Hello

“M” message header .

“108” I send 8 message .

“Hello” is my message.

’RA’ Message:

SendMessageBefore(newuser, Convert.ToInt32(System.Text.Encoding.ASCII.GetString(data).Substring(2, 3)));

When I get a service message or message and get the number of message which user last send and check this number with my number which last received check if it is not same then send back this message type and the last message number I get.

Example:

RA109

I have 9 message from you but you send bigger than this number I missed some send again this messages.

‘RR’ Message

When some messages are missed user send “RA” header message and include that the last message number received . RA header mesaji user aldığında mesajların başına RR ekleyerek eksik olan mesajları karşı taraf alıncaya kadar yollar.

Example:

RR101hello

Missed message number which is you didn’t get firs message which is “hello”.

“PO” Message:

PO header sahip olan mesaj karşı tarafın sizinle private room da chat yapmak istediğini belirtir. Bu mesaj geldiğinde mesajtaki numayı 5000 le toplayarak yeni bir udp port açar dinlemeye başlarsınız. Private room ayrı bir port kullanır mesajlaşmak için.

This message mean I want to private chat with you open your private room.

“E” Message:

This message mean that I closed my program delete me in your list .

Deleting user from Online List:

There are two ways for deleting someone from the list. There are two conditions for deleting users from the list. User can be deleted if two values are zero. These are activity and passive value in the user class. Deleteactivity thread works every 60000 ms. This thread makes activity value to zero. If a message comes then this value is 1 again. It is known that activity is already zero if passive value is zero then DeleteUserPermanently() function delete the user.After this process there will be a empty part in the user array and DeleteUser Permanently() function assign the last value in this empty part. DeleteUserPermanently() function also decreases user counter and resizes the array .

User can also be deleted by taking a E type header message from user. Sometimes runtime error can be occured. If this error occurs, user program closes.When user program closes, there may be a problem in sending this message or packet can be lost in the network.For this condition synchronization is provided by the first way.

Classes:

Mainwindow.cs:

It is the first class that when the program class starts.It has MDI property.Its childforms are privateroom form and publicroom form.

Mainwindow class provides that the main functions of program work and it controls the other forms. The processes of opening UDP port and waiting packet are also other jobs of the class. It has enter button, textbox for username and warning label for textbox. Moreover it has Statustoolstrips for controller.

There are three different threads in this form.Threads starts to work with sign in. After signing, user can leave the program via sign out that is in the file menu. Thread abort process is applied after sign out process. Abort process is edited by catching in AbortException because if thread sleeping mode Abort can’t handled. (Appendix D)

Main form makes a process with respect to state of arriving packets. It writes the messages on the screen by using class function. However, since private room has its own udp connection ,it only sends the IpEndPoint, name, port number and a sstring name of users , while user opens the privateroom.

NOTE: Class diagrams are given in the appendix part.

Publicroom

Publicroom works as a child of mainwindow form and it impossibe that publicroom has larger size than mainwindow. Textbox1, textbox2, listbox1, one send button and privateroom button are the content of publicroom.

Textbox1 is a textbox that mesages are written on and textbox2 is a textbox that arrived messages are written on.Online users are shown on the listbox1.Send button broadcasts the messages written on the textbox1. It also provides that the messages, cleaned form textbox1, are written on textbox2. Private button makes selected people connect privateroom.

Publicroom write the messages sent from mainwindow on the screen. It sends the messages ,written on the textbox1, firstly textbox2 then mainwindow class via the send button. Mainwindow class broadcoasts these coming messages.

To send a message from publicroom to mainwindow class, NotifyEventArgs, NotifyDaddyArgs, NotifyEnterArgs classes are used.

NotifyDaddyArgs is formed when send button is clicked. Textbox1 message is sent this class. The formation of this class causes performed of an other event in the mainwindow. (Appendix C)

UserOnlinePanel

Useronlinepanel is constracted by class mainwindow. Useronlinepanel uses the user class by assigning it an array variable. This class makes us to reach the information about user and helps synchronization part.This class mainly controls these ‘Does the message belong to new comer or someone on the list?’ ,‘Are the message numbers same?'

Users

User class is a class that stores the all online users information. Useripendpoint stores the last sent message number, nick name and activity state. It is called by Onlineuserarray which is an array variable in the useronlinepanel class. It uses Ipendpoint, name and an integer value as a construct value. Ip and port value of user is Ipendpoint. Name is the nickname of user and it is string. Integer value is the last sent message number.

NotifyDaddyEventArgs class:

Here are many ways to communicate from one form to another in a Windows Forms .NET application. However, when using MDI (Multiple Document Interface) mode, you may often find that the wiring up of simple events may better suit your need one of the simplest techniques for having a Child MDI form call back to its parent Container Form and even how to pass an object instance back to the Parent.

This class is formed when send button is clicked in the publicroom. Constructor takes the message as a parameter. After the construction of this class, it is handled in the main window.

NotifyEnterEventArgs class:

This class is necessary for sending message when user clicks the enter button. It works same as NotifyDaddyEventArgs

Points of Interest

there is no need server

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)