Chat Facility

> Networking application using WPF and the .NET Framework
> My Hand-in for Concurrent Network Applications Module for University



Learn More

View On Github

Project Overview

We were tasked to make a chat facility which allows users to communicate across a network

Server Features

  • > Set Max Number of Users
  • > Set Number of Users to Play Pictionary
  • > Console Output - Shows all data packets passed through server
  • > Threading for each client
  • > Automatically detects host and opens server on port 4444
  • > Packets system - for sending different types of data through the server
  • > Encryption and Security - Between Server and Client

Client Features

  • > Connection form - connect to any specified ip and port
  • > Easy to understand UI
  • > Chat to multiple clients through "main chat"
  • > Private Message clients
  • > Chat dropdown box - allows for easy private messaging
  • > Change nickname in real time
  • > Play Pictionary - Graphical Game

Code Snippets / Screenshots

Server - Handling Clients

The Server utilises threads to be able to handle inputs from each of the clients while also listening for new connections simultaneously
The code below shows how while the server is running the main thread will listen for new connections, if its a valid connection it will then offload this work to another thread to listen to packets this client may send.

while (serverRunning)
{
	Socket clientSocket = tcpListener.AcceptSocket();
	ConnectedClient newClient = new ConnectedClient(clientSocket);

	if (connectedClients.Count < maxClients)
	{
		connectedClients.Add(newClient);
		threads.Add(new Thread(() => { ClientMethod(connectedClients.Last()); }));
		threads.Last().Start();
	}
	else
	{
		TcpSendDataToSpecificClient(newClient, new Packets.DisconnectPacket());
	}
}							

Server - Packets

From the code snippet above we can see an example of a DisconnectPacket to allow specific data to be sent from clients to the server I created a packet system and methods for the server to send packets to all clients and specific clients. I have included the enum to show all the packets I created for the application.
> All packets follow the same format therefore I will only show one example here the rest can be found on the projects github repo

public enum PacketType
{
	ChatMessage,
	PrivateMessage,
	Nickname,
	Disconnect,
	Login,
	KeyPacket,
	ClientList,
	GameConnectionPacket,
	PictionaryChatMessage,
	PictionaryPaint,
	PictionaryClearCanvas,
	PictionarySetupClient,
	PictionaryWordToDraw,
	PictionaryClientList
}							
[Serializable()]
public class PrivateMessagePacket : Packet
{
	private byte[] message;
	private string targetUser;

	public PrivateMessagePacket(byte[] message, string targetUser)
	{
		this.message = message;
		this.targetUser = targetUser;
		m_PacketType = PacketType.PrivateMessage;
	}

	public byte[] Message
	{
		get { return message; }
		set { message = value; }
	}

	public string TargetUser
	{
		get { return targetUser; }
		protected set { }
	}
}							

Server - Security

The way in which the client and server have a layer of security is by using RSACryptoServiceProvider keys, the clients have their own keys and so does the server, upon loging into the server the client sends its key to the server and the server sends its key back, this allows for a basic level of security between our client and server where we utilise the keys to encrypt and decrypt messages.
> The below snippet is from the servers response to a client connecting, it creates a new instance of this client and sends back a key upon login.

public ConnectedClient(Socket socket)
{
	this.socket = socket;
	readLock = new object();
	writeLock = new object();

	stream = new NetworkStream(socket);
	writer = new BinaryWriter(stream);
	reader = new BinaryReader(stream);
	formatter = new BinaryFormatter();

	rsaProvider = new RSACryptoServiceProvider();
	publicKey = rsaProvider.ExportParameters(false);
	privateKey = rsaProvider.ExportParameters(true);
}

public void Login(string nickname, IPEndPoint endPoint, RSAParameters publicKey)
{
	this.nickname = nickname;
	this.endPoint = endPoint;
	clientKey = publicKey;

	TcpSend(new Packets.KeyPacket(this.publicKey));
}
					

Client

The majority of the clients code is handling data, for example, taking data from a text box converting it to a valid packet and sending it to the server because of this I will include more screenshots of the physical application as opposed to the code
The client has 3 main windows - The main interface, the connection form, and the pictionary game screen.

Pictionary

For the criteria of the project we needed to create a realtime graphical game for the users to play across the server, I decided to recreate pictionary
To allow for a working game I created specific features to allow for a fun game:

  • > Drawing with a pen
  • > Changing the brush colour
  • > Eraser tool
  • > Clear canvas button
  • > Chat for guessing and chatting
  • > System to only send the item being drawn to the "drawer"
  • > System to detect if the user has guessed correctly

A more in depth demonstration video was created for the project and I will be more than happy providing the video if requested.
The project has a lot more features which I am happy to discuss if needed.

View On Github